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/thai/base.llev");
let file = crate::phonetic::llev::parse_str(content)
.expect("Invalid embedded thai/base.llev - this is a bug in liblevenshtein");
RuleSetChar::from_llev(&file)
.expect("Failed to compile Thai 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(), "Thai base rules should not be empty");
assert!(
rules.len() >= 70,
"expected >=70 base rules, got {}",
rules.len()
);
}
#[test]
fn test_leading_vowels() {
let rules = base();
let result = rules.apply("เ");
assert!(result.contains('e'), "เ should become e, got: {}", result);
let result = rules.apply("แ");
assert!(result.contains("æ"), "แ should become ae, got: {}", result);
let result = rules.apply("โ");
assert!(result.contains('o'), "โ should become o, got: {}", result);
let result = rules.apply("ใ");
assert!(result.contains("aɪ"), "ใ should become ai, got: {}", result);
let result = rules.apply("ไ");
assert!(result.contains("aɪ"), "ไ should become ai, got: {}", result);
}
#[test]
fn test_following_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("am"), "ำ should become AM, got: {}", result);
}
#[test]
fn test_upper_vowels() {
let rules = base();
let result = rules.apply("ิ");
assert!(result.contains('i'), "ิ should become i, got: {}", result);
let result = rules.apply("ี");
assert!(
result.contains("iː") || result.contains('i'),
"ี should become iː, got: {}",
result
);
let result = rules.apply("ึ");
assert!(result.contains("ɯ"), "ึ should become ɯ, got: {}", result);
}
#[test]
fn test_lower_vowels() {
let rules = base();
let result = rules.apply("ุ");
assert!(result.contains('u'), "ุ should become u, got: {}", result);
let result = rules.apply("ู");
assert!(
result.contains("uː") || result.contains('u'),
"ู should become uː, got: {}",
result
);
}
#[test]
fn test_mid_class_consonants() {
let rules = base();
let result = rules.apply("ก");
assert!(result.contains('k'), "ก should become k, got: {}", result);
let result = rules.apply("จ");
assert!(result.contains('c'), "จ should become c, got: {}", result);
let result = rules.apply("บ");
assert!(result.contains('b'), "บ should become b, got: {}", result);
let result = rules.apply("ป");
assert!(result.contains('p'), "ป should become p, got: {}", result);
}
#[test]
fn test_high_class_consonants() {
let rules = base();
let result = rules.apply("ข");
assert!(
result.contains("kh") || result.contains('k'),
"ข should become kh, got: {}",
result
);
let result = rules.apply("ส");
assert!(result.contains('s'), "ส should become s, got: {}", result);
let result = rules.apply("ห");
assert!(result.contains('h'), "ห should become h, got: {}", result);
}
#[test]
fn test_low_class_consonants() {
let rules = base();
let result = rules.apply("ง");
assert!(result.contains("ŋ"), "ง should become ng, got: {}", result);
let result = rules.apply("ม");
assert!(result.contains('m'), "ม should become m, got: {}", result);
let result = rules.apply("ร");
assert!(result.contains('r'), "ร should become r, got: {}", result);
let result = rules.apply("ล");
assert!(result.contains('l'), "ล should become l, got: {}", result);
}
#[test]
fn test_word_thai() {
let rules = base();
let result = rules.apply_full("ไทย");
assert!(
result.contains("aɪ") && result.contains('y'),
"ไทย should contain AI, y, got: {}",
result
);
}
#[test]
fn test_word_bangkok() {
let rules = base();
let result = rules.apply_full("กรุงเทพ");
assert!(
result.contains('k') && result.contains('r'),
"กรุงเทพ should contain k, r, got: {}",
result
);
}
#[test]
fn test_word_sawatdi() {
let rules = base();
let result = rules.apply_full("สวัสดี");
assert!(
result.contains('s') && result.contains('w') && result.contains('d'),
"สวัสดี should contain s, w, d, got: {}",
result
);
}
#[test]
fn test_numerals() {
let rules = base();
let result = rules.apply("๐");
assert!(result.contains('0'), "๐ should become 0, got: {}", result);
let result = rules.apply("๕");
assert!(result.contains('5'), "๕ should become 5, got: {}", result);
let result = rules.apply("๙");
assert!(result.contains('9'), "๙ should become 9, got: {}", result);
}
}