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/czech/base.llev");
let file = crate::phonetic::llev::parse_str(content)
.expect("Invalid embedded czech/base.llev - this is a bug in liblevenshtein");
RuleSetChar::from_llev(&file)
.expect("Failed to compile Czech 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(), "Czech base rules should not be empty");
assert!(
rules.len() >= 15,
"expected >=15 base rules, got {}",
rules.len()
);
}
#[test]
fn test_c_hacek() {
let rules = base();
let result = rules.apply("č");
assert!(
result.contains("t͡ʃ"),
"č should produce t͡ʃ sound, got: {}",
result
);
}
#[test]
fn test_s_hacek() {
let rules = base();
let result = rules.apply("š");
assert!(result.contains("ʃ"), "š should become SH, got: {}", result);
}
#[test]
fn test_z_hacek() {
let rules = base();
let result = rules.apply("ž");
assert!(result.contains("ʒ"), "ž should become ZH, got: {}", result);
}
#[test]
fn test_r_hacek() {
let rules = base();
let result = rules.apply("ř");
assert!(result.contains("r̝"), "ř should become RZH, got: {}", result);
}
#[test]
fn test_soft_d() {
let rules = base();
let result = rules.apply("ď");
assert!(
result.contains("ɟ") || result.contains("d͡ʒ"),
"ď should become ɟ or d͡ʒ, got: {}",
result
);
}
#[test]
fn test_soft_t() {
let rules = base();
let result = rules.apply("ť");
assert!(
result.contains('c') || result.contains("tɕ") || result.contains("t͡s"),
"ť should become c (palatal plosive), tɕ, or t͡s, got: {}",
result
);
}
#[test]
fn test_soft_n() {
let rules = base();
let result = rules.apply("ň");
assert!(result.contains("ɲ"), "ň should become NJ, got: {}", result);
}
#[test]
fn test_long_a() {
let rules = base();
let result = rules.apply("á");
assert!(
result.contains("aː") || result.contains('a'),
"á should become aː or a, got: {}",
result
);
}
#[test]
fn test_u_ring() {
let rules = base();
let result = rules.apply("ů");
assert!(
result.contains("uː") || result.contains('u'),
"ů should become uː or u, got: {}",
result
);
}
#[test]
fn test_y_to_i() {
let rules = base();
let result = rules.apply("y");
assert!(result.contains('i'), "y should become i, got: {}", result);
}
#[test]
fn test_word_praha() {
let rules = base();
let result = rules.apply_full("praha");
let lower = result.to_lowercase();
assert!(
lower.contains('p') && lower.contains('r') && lower.contains('a'),
"praha should contain p, r, a, got: {}",
result
);
}
#[test]
fn test_word_cesko() {
let rules = base();
let result = rules.apply_full("česko");
assert!(
result.contains("t͡ʃ"),
"česko should contain CH, got: {}",
result
);
}
}