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/marathi/base.llev");
let file = crate::phonetic::llev::parse_str(content)
.expect("Invalid embedded marathi/base.llev - this is a bug in liblevenshtein");
RuleSetChar::from_llev(&file)
.expect("Failed to compile Marathi 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(), "Marathi base rules should not be empty");
assert!(
rules.len() >= 70,
"expected >=70 base rules, got {}",
rules.len()
);
}
#[test]
fn test_retroflex_lateral() {
let rules = base();
let result = rules.apply("ळ");
assert!(
result.contains("ɭ"),
"ळ should become ɭ (retroflex lateral), got: {}",
result
);
}
#[test]
fn test_ae_vowel() {
let rules = base();
let result = rules.apply("ऍ");
assert!(result.contains("æ"), "ऍ should become AE, got: {}", result);
}
#[test]
fn test_aw_vowel() {
let rules = base();
let result = rules.apply("ऑ");
assert!(result.contains("ɔ"), "ऑ should become AW, got: {}", result);
}
#[test]
fn test_independent_vowels() {
let rules = base();
let result = rules.apply("अ");
assert!(result.contains('a'), "अ should become a, got: {}", result);
let result = rules.apply("आ");
assert!(result.contains("aː"), "आ should become A, got: {}", result);
let result = rules.apply("इ");
assert!(result.contains('i'), "इ should become i, got: {}", result);
}
#[test]
fn test_velar_consonants() {
let rules = base();
let result = rules.apply("क");
assert!(result.contains('k'), "क should become k, got: {}", result);
let result = rules.apply("ख");
assert!(result.contains("kh"), "ख should become kh, got: {}", result);
let result = rules.apply("ग");
assert!(result.contains('ɡ'), "ग should become g, got: {}", result);
}
#[test]
fn test_retroflex_consonants() {
let rules = base();
let result = rules.apply("ट");
assert!(result.contains("ʈ"), "ट should become TT, got: {}", result);
let result = rules.apply("ड");
assert!(result.contains("ɖ"), "ड should become DD, got: {}", result);
let result = rules.apply("ण");
assert!(result.contains("ɳ"), "ण should become NN, got: {}", result);
}
#[test]
fn test_sibilants() {
let rules = base();
let result = rules.apply("श");
assert!(result.contains("ʃ"), "श should become SH, got: {}", result);
let result = rules.apply("ष");
assert!(result.contains("ʂ"), "ष should become SS, got: {}", result);
let result = rules.apply("स");
assert!(result.contains('s'), "स should become s, got: {}", result);
}
#[test]
fn test_vowel_matras() {
let rules = base();
let result = rules.apply("ा");
assert!(result.contains("aː"), "ा should become aː, got: {}", result);
let result = rules.apply("ि");
assert!(result.contains('i'), "ि should become i, got: {}", result);
let result = rules.apply("ै");
assert!(
result.contains("ɛː"),
"ै should become ɛː (ai diphthong), got: {}",
result
);
}
#[test]
fn test_word_marathi() {
let rules = base();
let result = rules.apply_full("मराठी");
assert!(
result.contains('m') && result.contains('r'),
"मराठी should contain m, r, got: {}",
result
);
}
#[test]
fn test_word_mumbai() {
let rules = base();
let result = rules.apply_full("मुंबई");
assert!(
result.contains('m') && result.contains('b'),
"मुंबई should contain m, b, got: {}",
result
);
}
#[test]
fn test_word_with_retroflex_lateral() {
let rules = base();
let result = rules.apply_full("बाळ");
assert!(
result.contains('b') && result.contains("ɭ"),
"बाळ should contain b, ɭ, got: {}",
result
);
}
#[test]
fn test_word_maharashtra() {
let rules = base();
let result = rules.apply_full("महाराष्ट्र");
assert!(
result.contains('m') && result.contains('h') && result.contains('r'),
"महाराष्ट्र should contain m, h, r, got: {}",
result
);
}
}