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/hungarian/base.llev");
let file = crate::phonetic::llev::parse_str(content)
.expect("Invalid embedded hungarian/base.llev - this is a bug in liblevenshtein");
RuleSetChar::from_llev(&file)
.expect("Failed to compile Hungarian 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(),
"Hungarian base rules should not be empty"
);
assert!(
rules.len() >= 50,
"expected >=50 base rules, got {}",
rules.len()
);
}
#[test]
fn test_dzs_trigraph() {
let rules = base();
let result = rules.apply("dzs");
assert!(
result.contains("d͡ʒ"),
"dzs should become DZS, got: {}",
result
);
}
#[test]
fn test_cs_digraph() {
let rules = base();
let result = rules.apply("cs");
assert!(
result.contains("t͡ʃ"),
"cs should become CH, got: {}",
result
);
}
#[test]
fn test_sz_digraph() {
let rules = base();
let result = rules.apply("sz");
assert!(
result.contains('s') || result.contains('ʃ'),
"sz should become s or ʃ (after s→ʃ rule), got: {}",
result
);
}
#[test]
fn test_zs_digraph() {
let rules = base();
let result = rules.apply("zs");
assert!(result.contains('ʒ'), "zs should become ʒ, got: {}", result);
}
#[test]
fn test_gy_digraph() {
let rules = base();
let result = rules.apply("gy");
assert!(result.contains("ɟ"), "gy should become GY, got: {}", result);
}
#[test]
fn test_ny_digraph() {
let rules = base();
let result = rules.apply("ny");
assert!(result.contains("ɲ"), "ny should become NY, got: {}", result);
}
#[test]
fn test_ly_digraph() {
let rules = base();
let result = rules.apply("ly");
assert!(result.contains('j'), "ly should become j, got: {}", result);
}
#[test]
fn test_ty_digraph() {
let rules = base();
let result = rules.apply("ty");
assert!(
result.contains('c') || result.contains("t͡s") || result.contains("t͡ʃ"),
"ty should become c, t͡s, or t͡ʃ (voiceless palatal plosive), got: {}",
result
);
}
#[test]
fn test_s_to_sh() {
let rules = base();
let result = rules.apply("s");
assert!(
result.contains("ʃ"),
"s should become SH (unique Hungarian!), got: {}",
result
);
}
#[test]
fn test_long_vowels() {
let rules = base();
let result = rules.apply("á");
assert!(result.contains("aː"), "á should become aː, got: {}", result);
let result = rules.apply("é");
assert!(result.contains("eː"), "é should become eː, got: {}", result);
let result = rules.apply("ó");
assert!(result.contains("oː"), "ó should become oː, got: {}", result);
}
#[test]
fn test_front_rounded_vowels() {
let rules = base();
let result = rules.apply("ö");
assert!(result.contains('ø'), "ö should become ø, got: {}", result);
let result = rules.apply("ő");
assert!(result.contains("øː"), "ő should become øː, got: {}", result);
let result = rules.apply("ü");
assert!(
result.contains('y') || result.contains('i'),
"ü should become y or i (after y→i rule at word end), got: {}",
result
);
let result = rules.apply("ű");
assert!(result.contains("yː"), "ű should become yː, got: {}", result);
}
#[test]
fn test_geminate_digraphs() {
let rules = base();
let result = rules.apply("ccs");
assert!(
result.contains("t͡ʃ"),
"ccs should become t͡ʃ, got: {}",
result
);
let result = rules.apply("ssz");
assert!(
result.contains('s') || result.contains('ʃ'),
"ssz should become s or ʃ (after s→ʃ rule), got: {}",
result
);
}
#[test]
fn test_word_magyar() {
let rules = base();
let result = rules.apply("magyar");
assert!(
result.contains("ɟ"),
"magyar should contain GY, got: {}",
result
);
}
#[test]
fn test_word_budapest() {
let rules = base();
let result = rules.apply("Budapest");
assert!(
result.contains("ʃ"),
"Budapest should contain SH (from s), got: {}",
result
);
}
}