use unicode_normalization::UnicodeNormalization;
pub fn convert_latn_to_cyrl(latn: &str) -> String {
let mut result = String::new();
let latn = latn.nfd().collect::<String>();
let mut chars = latn.chars().peekable();
while let Some(current_char) = chars.next() {
let current_lower = current_char.to_lowercase().next().unwrap();
let cyrl: Option<&str> = match chars.peek() {
Some(&next_char) if current_lower == 'y' && "uaoe".contains(next_char) => {
let next_lower = next_char.to_lowercase().next().unwrap();
chars.next();
match (current_lower, next_lower) {
('y', 'u') => Some("ю"),
('y', 'a') => Some("я"),
('y', 'o') => Some("ё"),
('y', 'e') => Some("е"),
_ => unreachable!(),
}
}
_ => match current_lower {
'a' => Some("а"),
'i' => Some("и"),
'u' => Some("у"),
'e' => Some("э"),
'o' => Some("о"),
'k' => Some("к"),
's' => Some("с"),
't' => Some("т"),
'c' => Some("ц"),
'h' => Some("х"),
'm' => Some("м"),
'n' => Some("н"),
'p' => Some("п"),
'r' => Some("р"),
'w' => Some("в"),
'y' => Some("й"),
'\'' => Some("ъ"),
'’' => Some(""),
_ => None,
},
};
let cyrl_result = match cyrl {
Some(c) => {
if current_char.is_uppercase() {
c.chars().flat_map(char::to_uppercase).collect::<String>()
} else {
c.to_string()
}
}
None => current_char.to_string(),
};
result.push_str(&cyrl_result);
}
result
}
pub fn convert_cyrl_to_latn(cyrl: &str) -> String {
let mut result = String::new();
let mut chars = cyrl.chars().peekable();
while let Some(current_char) = chars.next() {
let current_lower = current_char.to_lowercase().next().unwrap();
let cyrl: Option<&str> = match chars.peek() {
Some(&next_char) if current_lower == 'й' && "уаоэ".contains(next_char) => {
let next_lower = next_char.to_lowercase().next().unwrap();
chars.next();
match next_lower {
'у' => Some("y’u"),
'а' => Some("y’a"),
'о' => Some("y’o"),
'э' => Some("y’e"),
_ => unreachable!(),
}
}
_ => match current_lower {
'ю' => Some("yu"),
'я' => Some("ya"),
'ё' => Some("yo"),
'е' => Some("ye"),
'а' => Some("a"),
'и' => Some("i"),
'у' => Some("u"),
'э' => Some("e"),
'о' => Some("o"),
'к' => Some("k"),
'с' => Some("s"),
'т' => Some("t"),
'ц' => Some("c"),
'х' => Some("h"),
'м' => Some("m"),
'н' => Some("n"),
'п' => Some("p"),
'р' => Some("r"),
'в' => Some("w"),
'й' => Some("y"),
'ъ' => Some("'"),
'ь' => None,
'’' => None,
' ' => None,
_ => None,
},
};
let cyrl_result = match cyrl {
Some(c) => {
if current_char.is_uppercase() {
c.chars().flat_map(char::to_uppercase).collect::<String>()
} else {
c.to_string()
}
}
None => current_char.to_string(),
};
result.push_str(&cyrl_result);
}
result.nfc().collect::<String>()
}