pub fn transliterate_dstu9112a(text: &str) -> String {
let chars: Vec<char> = text.chars().collect();
let mut output = String::with_capacity(text.len() * 2);
let mut index = 0usize;
while index < chars.len() {
let ch = chars[index];
let next = chars.get(index + 1).copied();
match ch {
'Щ' | 'щ' => {
output.push_str(transliterate_shcha(ch, next));
index += 1;
}
'Ь' | 'ь' => {
output.push_str(transliterate_soft_sign(ch, next));
index += 1;
}
'Х' | 'х' => {
output.push_str(if ch.is_uppercase() { "X" } else { "x" });
index += 1;
}
'’' | '\'' => {
output.push('’');
index += 1;
}
_ => {
if let Some(mapped) = map_basic(ch) {
output.push_str(mapped);
} else {
output.push(ch);
}
index += 1;
}
}
}
output
}
fn transliterate_shcha(current: char, next: Option<char>) -> &'static str {
let is_upper = current.is_uppercase();
match next {
Some('а') | Some('А') | Some('я') | Some('Я') | Some('ю') | Some('Ю') | Some('є')
| Some('Є') => {
if is_upper {
"Šč"
} else {
"šč"
}
}
Some('і') | Some('І') | Some('ї') | Some('Ї') | Some('й') | Some('Й') | Some('ь')
| Some('Ь') | Some('е') | Some('Е') | Some('о') | Some('О') | Some('и') | Some('И') => {
if is_upper {
"Ŝ"
} else {
"ŝ"
}
}
_ => {
if is_upper {
"Šč"
} else {
"šč"
}
}
}
}
fn transliterate_soft_sign(current: char, next: Option<char>) -> &'static str {
match next {
Some('в') | Some('В') => "’",
_ => {
if current.is_uppercase() {
"J"
} else {
"j"
}
}
}
}
fn map_basic(ch: char) -> Option<&'static str> {
match ch {
'А' => Some("A"),
'а' => Some("a"),
'Б' => Some("B"),
'б' => Some("b"),
'В' => Some("V"),
'в' => Some("v"),
'Г' => Some("Ğ"),
'г' => Some("ğ"),
'Ґ' => Some("G"),
'ґ' => Some("g"),
'Д' => Some("D"),
'д' => Some("d"),
'Е' => Some("E"),
'е' => Some("e"),
'Є' => Some("Je"),
'є' => Some("je"),
'Ж' => Some("Ž"),
'ж' => Some("ž"),
'З' => Some("Z"),
'з' => Some("z"),
'И' => Some("Y"),
'и' => Some("y"),
'І' => Some("I"),
'і' => Some("i"),
'Ї' => Some("Ï"),
'ї' => Some("ï"),
'Й' => Some("J"),
'й' => Some("j"),
'К' => Some("K"),
'к' => Some("k"),
'Л' => Some("L"),
'л' => Some("l"),
'М' => Some("M"),
'м' => Some("m"),
'Н' => Some("N"),
'н' => Some("n"),
'О' => Some("O"),
'о' => Some("o"),
'П' => Some("P"),
'п' => Some("p"),
'Р' => Some("R"),
'р' => Some("r"),
'С' => Some("S"),
'с' => Some("s"),
'Т' => Some("T"),
'т' => Some("t"),
'У' => Some("U"),
'у' => Some("u"),
'Ф' => Some("F"),
'ф' => Some("f"),
'Х' => Some("X"),
'х' => Some("x"),
'Ц' => Some("C"),
'ц' => Some("c"),
'Ч' => Some("Č"),
'ч' => Some("č"),
'Ш' => Some("Š"),
'ш' => Some("š"),
'Ю' => Some("Ju"),
'ю' => Some("ju"),
'Я' => Some("Ja"),
'я' => Some("ja"),
'Ь' => Some("’"),
'ь' => Some("’"),
_ => None,
}
}