1use unicode_normalization::UnicodeNormalization;
2
3pub fn normalize(text: &str) -> String {
5 text.nfkc()
6 .flat_map(char::to_lowercase)
7 .map(fold_width_compatible_char)
8 .collect()
9}
10
11pub fn fold_width_compatible_char(ch: char) -> char {
13 match ch {
14 '-' | '\u{2010}' | '\u{2011}' | '\u{2012}' | '\u{2013}' | '\u{2014}' | '\u{2015}'
15 | '\u{2212}' | '\u{30a0}' | '\u{30fc}' | '\u{fe58}' | '\u{fe63}' | '\u{ff0d}'
16 | '\u{ff70}' => '-',
17 _ => ch,
18 }
19}
20
21pub fn katakana_to_hiragana(text: &str) -> String {
23 text.chars()
24 .map(|ch| {
25 if ('ァ'..='ヶ').contains(&ch) {
26 char::from_u32(ch as u32 - 0x60).unwrap_or(ch)
27 } else {
28 ch
29 }
30 })
31 .collect()
32}
33
34pub fn hiragana_to_katakana(text: &str) -> String {
36 text.chars()
37 .map(|ch| {
38 if ('ぁ'..='ゖ').contains(&ch) {
39 char::from_u32(ch as u32 + 0x60).unwrap_or(ch)
40 } else {
41 ch
42 }
43 })
44 .collect()
45}
46
47pub fn contains_kana(text: &str) -> bool {
49 text.chars()
50 .any(|ch| ('ぁ'..='ゖ').contains(&ch) || ('ァ'..='ヶ').contains(&ch))
51}
52
53#[cfg(test)]
54mod tests;