use super::CharsMapping;
use std::cmp::Ordering;
use crate::bulgarian;
use crate::gost779;
use crate::macedonian;
use crate::order_n_995;
use crate::passport2013;
pub trait ToLatin {
fn to_latin(&self, src: &str) -> String;
}
pub trait FromLatin {
fn from_latin(&self, src: &str) -> String;
}
pub enum Language {
Ru,
By,
Ua,
}
pub struct Transliterator {
rules: CharsMapping,
}
impl Transliterator {
pub fn new(custom_rules: CharsMapping) -> Self {
let mut table = custom_rules;
fn compare_len(left: &str, right: &str) -> Ordering {
if left.len() == right.len() {
Ordering::Equal
} else if left.len() > right.len() {
Ordering::Greater
} else {
Ordering::Less
}
}
table.sort_by(|a, b| compare_len(b.1, a.1));
Self { rules: table }
}
pub fn convert(&self, src: &str, invert: bool) -> String {
let mut input = src.to_owned();
for elem in self.rules.iter() {
let (source_char, translit_char) = (elem.0, elem.1);
input = {
if invert {
input.replace(translit_char, source_char)
} else {
input.replace(source_char, translit_char)
}
}
}
input
}
}
impl ToLatin for Transliterator {
fn to_latin(&self, src: &str) -> String {
self.convert(src, false)
}
}
impl FromLatin for Transliterator {
fn from_latin(&self, src: &str) -> String {
self.convert(src, true)
}
}
pub struct Gost779B {
translit: Transliterator,
}
impl Gost779B {
pub fn new(lang: Language) -> Gost779B {
let table = match lang {
Language::Ru => gost779::gost779b_ru(),
Language::By => gost779::gost779b_by(),
Language::Ua => gost779::gost779b_ua(),
};
let translit = Transliterator::new(table);
Gost779B { translit }
}
}
impl ToLatin for Gost779B {
fn to_latin(&self, src: &str) -> String {
self.translit.to_latin(src)
}
}
impl FromLatin for Gost779B {
fn from_latin(&self, src: &str) -> String {
self.translit.from_latin(src)
}
}
pub struct Passport2013 {
translit: Transliterator,
}
impl Passport2013 {
pub fn new() -> Passport2013 {
let translit = Transliterator::new(passport2013::iternational_passport_2013_ru());
Passport2013 { translit }
}
}
impl ToLatin for Passport2013 {
fn to_latin(&self, src: &str) -> String {
self.translit.to_latin(src)
}
}
pub struct OrderN995 {
translit: Transliterator,
}
impl OrderN995 {
pub fn new() -> Self {
let translit = Transliterator::new(order_n_995::order_n_995_ru());
OrderN995 { translit }
}
}
impl ToLatin for OrderN995 {
fn to_latin(&self, src: &str) -> String {
self.translit.to_latin(src)
}
}
pub struct BulgarianOfficial {
translit: Transliterator,
}
impl BulgarianOfficial {
pub fn new() -> BulgarianOfficial {
let translit = Transliterator::new(bulgarian::streamlined_system());
BulgarianOfficial { translit }
}
}
impl ToLatin for BulgarianOfficial {
fn to_latin(&self, src: &str) -> String {
self.translit.to_latin(src)
}
}
pub struct MacedonianOfficial {
translit: Transliterator,
}
impl MacedonianOfficial {
pub fn new() -> MacedonianOfficial {
let translit = Transliterator::new(macedonian::digraph_system());
MacedonianOfficial { translit }
}
}
impl ToLatin for MacedonianOfficial {
fn to_latin(&self, src: &str) -> String {
self.translit.to_latin(src)
}
}