use serde::Deserialize;
use super::PatternAtom;
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Mapping {
pub ipa: String,
pub roman: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContextualRule {
pub roman: String,
pub ipa: String,
pub before: Option<PatternAtom>,
pub after: Option<PatternAtom>,
}
#[derive(Deserialize)]
struct RawContextual {
roman: String,
ipa: String,
#[serde(default)]
before: Option<String>,
#[serde(default)]
after: Option<String>,
}
fn atom(s: Option<String>) -> Option<PatternAtom> {
let t = s?;
let t = t.trim();
if t.is_empty() {
None
} else if t == "#" {
Some(PatternAtom::Boundary)
} else {
Some(PatternAtom::Symbol(t.to_string()))
}
}
impl<'de> Deserialize<'de> for ContextualRule {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let r = RawContextual::deserialize(d)?;
Ok(ContextualRule {
roman: r.roman,
ipa: r.ipa,
before: atom(r.before),
after: atom(r.after),
})
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct RomanizationScheme {
pub name: String,
#[serde(default)]
pub mappings: Vec<Mapping>,
#[serde(default)]
pub contextual: Vec<ContextualRule>,
}