|
|
@ -1,3 +1,4 @@
|
|
|
|
|
|
|
|
use core::panic;
|
|
|
|
use std::str::FromStr;
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
|
|
|
|
use serde::{Deserialize, Deserializer, Serialize};
|
|
|
|
use serde::{Deserialize, Deserializer, Serialize};
|
|
|
@ -42,40 +43,49 @@ impl<'de> Deserialize<'de> for ChallengeWord {
|
|
|
|
&"a string or map",
|
|
|
|
&"a string or map",
|
|
|
|
));
|
|
|
|
));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let dictionary = map.get("dictionary").and_then(|value| match value {
|
|
|
|
let text = map.get("text").map(|value| match value {
|
|
|
|
Value::Null => None,
|
|
|
|
Value::String(string) => vec![Furigana {
|
|
|
|
_ => Some(value.as_str().unwrap().to_owned()),
|
|
|
|
kanji: string.clone(),
|
|
|
|
|
|
|
|
furigana: None,
|
|
|
|
|
|
|
|
}],
|
|
|
|
|
|
|
|
Value::Sequence(sequence) => sequence
|
|
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.map(|value| match value {
|
|
|
|
|
|
|
|
Value::String(kanji) => Furigana {
|
|
|
|
|
|
|
|
kanji: kanji.to_owned(),
|
|
|
|
|
|
|
|
furigana: None,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Value::Mapping(mapping) => {
|
|
|
|
|
|
|
|
let (kanji, furigana) = mapping.iter().next().unwrap();
|
|
|
|
|
|
|
|
Furigana {
|
|
|
|
|
|
|
|
kanji: kanji.as_str().unwrap().to_owned(),
|
|
|
|
|
|
|
|
furigana: Some(furigana.as_str().unwrap().to_owned()),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => panic!(),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.collect(),
|
|
|
|
|
|
|
|
_ => panic!(),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
let dictionary = match map.get("dictionary") {
|
|
|
|
|
|
|
|
Some(value) => match value {
|
|
|
|
|
|
|
|
Value::Null => None,
|
|
|
|
|
|
|
|
Value::String(dictionary) => Some(if !dictionary.starts_with("http") {
|
|
|
|
|
|
|
|
format!("https://jisho.org/word/{dictionary}")
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
dictionary.to_owned()
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
_ => panic!("dictionary must be string!"),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
None => text.as_ref().map(|furigana| furigana.iter().map(|segment| segment.kanji.clone()).collect()),
|
|
|
|
|
|
|
|
};
|
|
|
|
let pos: Option<PartOfSpeech> = map
|
|
|
|
let pos: Option<PartOfSpeech> = map
|
|
|
|
.get("pos")
|
|
|
|
.get("pos")
|
|
|
|
.map(|value| value.as_str().unwrap().parse().unwrap());
|
|
|
|
.map(|value| value.as_str().unwrap().parse().unwrap());
|
|
|
|
Ok(ChallengeWord {
|
|
|
|
Ok(ChallengeWord {
|
|
|
|
dictionary,
|
|
|
|
dictionary,
|
|
|
|
pos,
|
|
|
|
pos,
|
|
|
|
text: map.get("text").map(|value| match value {
|
|
|
|
text,
|
|
|
|
Value::String(string) => vec![Furigana {
|
|
|
|
|
|
|
|
kanji: string.clone(),
|
|
|
|
|
|
|
|
furigana: None,
|
|
|
|
|
|
|
|
}],
|
|
|
|
|
|
|
|
Value::Sequence(sequence) => sequence
|
|
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.map(|value| match value {
|
|
|
|
|
|
|
|
Value::String(kanji) => Furigana {
|
|
|
|
|
|
|
|
kanji: kanji.to_owned(),
|
|
|
|
|
|
|
|
furigana: None,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Value::Mapping(mapping) => {
|
|
|
|
|
|
|
|
let (kanji, furigana) = mapping.iter().next().unwrap();
|
|
|
|
|
|
|
|
Furigana {
|
|
|
|
|
|
|
|
kanji: kanji.as_str().unwrap().to_owned(),
|
|
|
|
|
|
|
|
furigana: Some(furigana.as_str().unwrap().to_owned()),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => panic!(),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.collect(),
|
|
|
|
|
|
|
|
_ => panic!(),
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|