use crate::phonetic::llev::RuleSetChar;
use std::sync::OnceLock;
pub fn base() -> &'static RuleSetChar {
static RULESET: OnceLock<RuleSetChar> = OnceLock::new();
RULESET.get_or_init(|| {
let content = include_str!("../../../data/rules/armenian/base.llev");
let file = crate::phonetic::llev::parse_str(content)
.expect("Invalid embedded armenian/base.llev - this is a bug in liblevenshtein");
RuleSetChar::from_llev(&file)
.expect("Failed to compile Armenian base rules - this is a bug in liblevenshtein")
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_base_loads() {
let rules = base();
assert!(!rules.is_empty(), "Armenian base rules should not be empty");
assert!(
rules.len() >= 50,
"expected >=50 base rules, got {}",
rules.len()
);
}
#[test]
fn test_uppercase_vowels() {
let rules = base();
let result = rules.apply("\u{0531}");
assert!(result.contains('a'), "Ա should become a, got: {}", result);
let result = rules.apply("\u{0535}");
assert!(result.contains('e'), "Ե should become e, got: {}", result);
let result = rules.apply("\u{053B}");
assert!(result.contains('i'), "Ի should become i, got: {}", result);
let result = rules.apply("\u{0548}");
assert!(result.contains('o'), "Ո should become o, got: {}", result);
}
#[test]
fn test_lowercase_vowels() {
let rules = base();
let result = rules.apply("\u{0561}");
assert!(
result.contains('a'),
" delays should become a, got: {}",
result
);
let result = rules.apply("\u{0565}");
assert!(result.contains('e'), "ե should become e, got: {}", result);
let result = rules.apply("\u{056B}");
assert!(
result.contains('i'),
" delays should become i, got: {}",
result
);
let result = rules.apply("\u{0578}");
assert!(result.contains('o'), "ո should become o, got: {}", result);
}
#[test]
fn test_voiced_stops() {
let rules = base();
let result = rules.apply("\u{0532}");
assert!(result.contains('b'), "Բ should become b, got: {}", result);
let result = rules.apply("\u{0533}");
assert!(result.contains('ɡ'), "Գ should become g, got: {}", result);
let result = rules.apply("\u{0534}");
assert!(
result.contains('d'),
"Delays should become d, got: {}",
result
);
}
#[test]
fn test_aspirated_stops() {
let rules = base();
let result = rules.apply("\u{0539}");
assert!(
result.contains('t'),
"U+0539 (to) should become t (T simplified), got: {}",
result
);
let result = rules.apply("\u{0553}");
assert!(
result.contains('p'),
"U+0553 (piwr) should become p (P simplified), got: {}",
result
);
let result = rules.apply("\u{0554}");
assert!(
result.contains('k'),
"U+0554 (ke) should become k (K simplified), got: {}",
result
);
}
#[test]
fn test_plain_voiceless_stops() {
let rules = base();
let result = rules.apply("\u{054F}");
assert!(result.contains('t'), "Տ should become t, got: {}", result);
let result = rules.apply("\u{054A}");
assert!(result.contains('p'), "Պ should become p, got: {}", result);
let result = rules.apply("\u{053F}");
assert!(
result.contains('k'),
"Delays should become k, got: {}",
result
);
}
#[test]
fn test_affricates() {
let rules = base();
let result = rules.apply("\u{053E}");
assert!(
result.contains("t͡s"),
"U+053E (tsa) should become t͡s, got: {}",
result
);
let result = rules.apply("\u{0541}");
assert!(
result.contains("d͡z"),
"U+0541 (ja) should become d͡z, got: {}",
result
);
let result = rules.apply("\u{054B}");
assert!(
result.contains("d͡ʒ"),
"U+054B (je) should become d͡ʒ, got: {}",
result
);
}
#[test]
fn test_sibilants() {
let rules = base();
let result = rules.apply("\u{0536}");
assert!(
result.contains('z'),
"U+0536 (za) should become z, got: {}",
result
);
let result = rules.apply("\u{054D}");
assert!(
result.contains('s'),
"U+054D (se) should become s, got: {}",
result
);
let result = rules.apply("\u{0547}");
assert!(
result.contains("ʃ"),
"U+0547 (sha) should become sh (SH simplified), got: {}",
result
);
let result = rules.apply("\u{053A}");
assert!(
result.contains("ʒ"),
"U+053A (zhe) should become zh (ZH simplified), got: {}",
result
);
}
#[test]
fn test_other_fricatives() {
let rules = base();
let result = rules.apply("\u{0540}");
assert!(
result.contains('h'),
"U+0540 (ho) should become h, got: {}",
result
);
let result = rules.apply("\u{053D}");
assert!(
result.contains('x'),
"U+053D (xe) should become x, got: {}",
result
);
let result = rules.apply("\u{0542}");
assert!(
result.contains("ɣ"),
"U+0542 (ghat) should become gh (GH simplified), got: {}",
result
);
}
#[test]
fn test_nasals() {
let rules = base();
let result = rules.apply("\u{0544}");
assert!(
result.contains('m'),
"Delays should become m, got: {}",
result
);
let result = rules.apply("\u{0546}");
assert!(result.contains('n'), "Ն should become n, got: {}", result);
}
#[test]
fn test_liquids() {
let rules = base();
let result = rules.apply("\u{053C}");
assert!(
result.contains('l'),
"U+053C (liwn) should become l, got: {}",
result
);
let result = rules.apply("\u{0550}");
assert!(
result.contains('r'),
"U+0550 (re) should become r, got: {}",
result
);
let result = rules.apply("\u{054C}");
assert!(
result.contains("RR") || result.contains('r'),
"U+054C (ra) should become RR (trilled r), got: {}",
result
);
}
#[test]
fn test_approximants() {
let rules = base();
let result = rules.apply("\u{054E}");
assert!(
result.contains('v'),
"Delays should become v, got: {}",
result
);
let result = rules.apply("\u{0545}");
assert!(
result.contains('y'),
"Delays should become y, got: {}",
result
);
}
#[test]
fn test_word_hayeren() {
let rules = base();
let result = rules.apply_full("\u{0540}\u{0561}\u{0575}\u{0565}\u{0580}\u{0565}\u{0576}");
assert!(
result.contains('h') && result.contains('a') && result.contains('y'),
"Հdelays ε delays delays ε delays should contain h, a, y, got: {}",
result
);
}
#[test]
fn test_word_yerevan() {
let rules = base();
let result = rules.apply_full("\u{0535}\u{0580}\u{0565}\u{057E}\u{0561}\u{0576}");
assert!(
result.contains('e') && result.contains('r') && result.contains('v'),
"Delays delays ε delays delays delays should contain e, r, v, got: {}",
result
);
}
}