use serde::Deserialize;
use serde_json::Value;
#[derive(Debug, Deserialize)]
pub struct Sense {
pub definitions: Option<Vec<String>>,
pub examples: Option<Vec<Example>>,
pub subsenses: Option<Vec<Sense>>,
pub domains: Option<Vec<Domain>>,
#[serde(rename = "crossReferenceMarkers")]
pub cross_reference_markers: Option<Vec<String>>,
pub registers: Option<Vec<Register>>,
}
#[derive(Debug, Deserialize)]
pub struct VariantForm {
pub regions: Option<Vec<Region>>,
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct Entry {
pub senses: Option<Vec<Sense>>,
pub pronunciations: Option<Vec<Pronunciation>>,
#[serde(rename = "variantForms")]
pub variant_forms: Option<Vec<VariantForm>>,
#[serde(rename = "etymologies")]
pub origins: Option<Vec<String>>,
}
#[derive(Debug, Deserialize)]
pub struct LexicalEntry {
pub entries: Vec<Entry>,
pub language: String,
#[serde(rename = "lexicalCategory")]
pub lexical_category: LexicalCategory,
#[serde(rename = "derivativeOf")]
pub derivative_of: Option<Vec<DerivativeOf>>,
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct HeadwordEntry {
pub id: String,
pub language: String,
#[serde(rename = "lexicalEntries")]
pub lexical_entries: Vec<LexicalEntry>,
#[serde(rename = "type")]
pub type_: String,
pub word: String,
}
#[derive(Debug, Deserialize)]
pub struct RetrieveEntry {
pub id: Option<String>,
pub metadata: Value,
#[serde(rename = "results")]
pub headword_entries: Vec<HeadwordEntry>,
pub word: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct LexicalCategory {
pub id: String,
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct Example {
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct Pronunciation {
#[serde(rename = "phoneticSpelling")]
pub phonetic_spelling: Option<String>,
#[serde(rename = "phoneticNotation")]
pub phonetic_notation: String,
#[serde(rename = "audioFile")]
pub audio_file: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct Domain {
pub id: String,
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct Register {
pub id: String,
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct Region {
pub id: String,
pub text: String,
}
#[derive(Debug, Deserialize, Clone)]
pub struct DerivativeOf {
pub id: String,
pub text: String,
}
impl PartialEq for Pronunciation {
fn eq(&self, other: &Self) -> bool {
self.phonetic_notation == other.phonetic_notation
&& self.phonetic_spelling == other.phonetic_spelling
}
}
impl Eq for Pronunciation {}
pub fn has_consistent_pronunciation(headword: &HeadwordEntry) -> bool {
let lexical_entries = &headword.lexical_entries;
let mut pronunciations: Vec<&Vec<Pronunciation>> = Vec::new();
for lexical_entry in lexical_entries {
for entry in &lexical_entry.entries {
if let Some(p) = &entry.pronunciations {
pronunciations.push(p);
}
}
}
return have_same_elements(pronunciations);
}
fn have_same_elements<T: Eq>(vv: Vec<&Vec<T>>) -> bool {
if vv.len() <= 1 {
return true;
}
for e1 in vv[0] {
for v in &vv[1..] {
if !v.contains(&e1) {
return false;
}
}
}
return true;
}
#[test]
fn test_have_same_elements() {
let v123 = vec![1, 2, 3];
let v124 = vec![1, 2, 4];
let vv1 = vec![&v123, &v123];
let vv2 = vec![&v123];
let vv3: Vec<&Vec<isize>> = vec![];
let vv4 = vec![&v123, &v124];
assert_eq!(have_same_elements(vv1), true);
assert_eq!(have_same_elements(vv2), true);
assert_eq!(have_same_elements(vv3), true);
assert_eq!(have_same_elements(vv4), false);
}
pub fn is_empty_entries(entries: &Vec<Entry>) -> bool {
return entries.iter().all(|entry| {
entry.pronunciations.is_none() && entry.senses.is_none() && entry.variant_forms.is_none()
});
}
pub fn is_empty_sense(sense: &Sense) -> bool {
sense.definitions.is_none() && sense.cross_reference_markers.is_none()
}
pub fn roots(retrieve_entry: &RetrieveEntry) -> Vec<DerivativeOf> {
let mut roots: Vec<DerivativeOf> = vec![];
for headword in &retrieve_entry.headword_entries {
for lexical_entry in &headword.lexical_entries {
if let Some(derivative_ofs) = &lexical_entry.derivative_of {
roots.append(&mut derivative_ofs.clone());
}
}
}
roots
}
impl HeadwordEntry {
pub fn origins<'a>(&'a self) -> Vec<&'a String> {
self.lexical_entries
.iter()
.flat_map(|lexical_entry| {
lexical_entry
.entries
.iter()
.filter_map(|e| e.origins.as_ref())
.flatten()
})
.collect()
}
}