use std::collections::HashMap;
use std::sync::LazyLock;
static READINGS: &str = include_str!("../resources/hanja-readings.txt");
static INDEX: LazyLock<HashMap<char, &'static str>> = LazyLock::new(|| {
READINGS
.lines()
.filter_map(|line| {
let (hanja, reading) = line.split_once('\t')?;
let mut chars = hanja.chars();
let hanja = chars.next()?;
(chars.next().is_none() && !reading.is_empty()).then_some((hanja, reading))
})
.collect()
});
pub fn is_hanja(c: char) -> bool {
matches!(c,
'\u{3400}'..='\u{4DBF}'
| '\u{4E00}'..='\u{9FFF}'
| '\u{F900}'..='\u{FAFF}'
| '\u{20000}'..='\u{2A6DF}'
| '\u{2F800}'..='\u{2FA1F}')
}
pub fn reading(c: char) -> Option<&'static str> {
INDEX.get(&c).copied()
}
#[cfg(test)]
mod tests {
use super::*;
#[rstest::rstest]
#[case::state('州', "주")]
#[case::before('前', "전")]
#[case::late('故', "고")]
#[case::branch('支', "지")]
#[case::line('線', "선")]
#[case::fragrance('香', "향")]
#[case::river('川', "천")]
#[case::present('現', "현")]
fn reads_corpus_hanja(#[case] hanja: char, #[case] expected: &str) {
assert_eq!(reading(hanja), Some(expected));
}
#[test]
fn hangul_and_latin_are_not_hanja() {
assert!(!is_hanja('가'));
assert!(!is_hanja('A'));
assert!(is_hanja('州'));
}
#[test]
fn hanja_in_a_sentence_uses_its_reading() {
assert_eq!(
crate::encode_to_unicode("지선(支線)"),
crate::encode_to_unicode("지선(지선)")
);
}
}