cirilica/
lib.rs

1mod utils;
2
3use wasm_bindgen::prelude::*;
4
5// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
6// allocator.
7#[cfg(feature = "wee_alloc")]
8#[global_allocator]
9static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
10
11#[wasm_bindgen]
12/// transform utf-8 serbian latinic to serbian cyrilic
13/// also translate two letters nj,lj and dž
14/// and capital Nj,Lj and Dž
15/// in one cyrilic letter  
16pub fn latin_to_cyrillic(input: String) -> String {
17    let mut output = String::new();
18    let mut iter = input.chars().peekable();
19
20    while let Some(c) = iter.next() {
21        match c {
22            's' => output.push('с'),
23            'o' => output.push('о'),
24            'e' => output.push('е'),
25            'a' => output.push('а'),
26            'i' => output.push('и'),
27            'n' => {
28                if let Some(&next) = iter.peek() {
29                    if next == 'j' {
30                        output.push('њ');
31                        iter.next();
32                    } else {
33                        output.push('н');
34                    }
35                } else {
36                    output.push('н');
37                }
38            }
39            't' => output.push('т'),
40            'r' => output.push('р'),
41            'd' => {
42                if let Some(&next) = iter.peek() {
43                    if next == 'ž' {
44                        output.push('џ');
45                        iter.next();
46                    } else {
47                        output.push('д');
48                    }
49                } else {
50                    output.push('д');
51                }
52            }
53            'l' => {
54                if let Some(&next) = iter.peek() {
55                    if next == 'j' {
56                        output.push('љ');
57                        iter.next();
58                    } else {
59                        output.push('л');
60                    }
61                } else {
62                    output.push('л');
63                }
64            }
65            'u' => output.push('у'),
66            'k' => output.push('к'),
67            'm' => output.push('м'),
68            'b' => output.push('б'),
69            'p' => output.push('п'),
70            'z' => output.push('з'),
71            'š' => output.push('ш'),
72            'v' => output.push('в'),
73            'j' => output.push('ј'),
74            'h' => output.push('х'),
75            'f' => output.push('ф'),
76            'ž' => output.push('ж'),
77            'g' => output.push('г'),
78            'c' => output.push('ц'),
79            'č' => output.push('ч'),
80            'đ' => output.push('ђ'),
81            'ć' => output.push('ћ'),
82            'S' => output.push('С'),
83            'O' => output.push('О'),
84            'E' => output.push('Е'),
85            'I' => output.push('И'),
86            'A' => output.push('А'),
87            'N' => {
88                if let Some(&next) = iter.peek() {
89                    if next == 'j' {
90                        output.push('Њ');
91                        iter.next();
92                    } else {
93                        output.push('Н');
94                    }
95                } else {
96                    output.push('Н');
97                }
98            }
99            'T' => output.push('Т'),
100            'R' => output.push('Р'),
101            'D' => {
102                if let Some(&next) = iter.peek() {
103                    if next == 'ž' {
104                        output.push('Џ');
105                        iter.next();
106                    } else {
107                        output.push('Д');
108                    }
109                } else {
110                    output.push('Д');
111                }
112            }
113            'L' => {
114                if let Some(&next) = iter.peek() {
115                    if next == 'j' {
116                        output.push('Љ');
117                        iter.next();
118                    } else {
119                        output.push('Л');
120                    }
121                } else {
122                    output.push('Л');
123                }
124            }
125            'U' => output.push('У'),
126            'K' => output.push('К'),
127            'M' => output.push('М'),
128            'B' => output.push('Б'),
129            'P' => output.push('П'),
130            'Z' => output.push('З'),
131            'Š' => output.push('Ш'),
132            'V' => output.push('В'),
133            'J' => output.push('Ј'),
134            'H' => output.push('Х'),
135            'F' => output.push('Ф'),
136            'Ž' => output.push('Ж'),
137            'G' => output.push('Г'),
138            'C' => output.push('Ц'),
139            'Č' => output.push('Ч'),
140            'Ć' => output.push('Ћ'),
141            'Đ' => output.push('Ђ'),
142            _ => output.push(c),
143        }
144    }
145
146    output
147}
148/// transform utf-8 serbian latinic to serbian cyrilic
149/// does translate two letters nj,lj and dž
150/// and capital Nj,Lj and Dž
151/// in one cyrilic letter but
152/// in 2 cyrilic letters  
153
154#[cfg(test)]
155mod tests {
156    // Note this useful idiom: importing names from outer (for mod tests) scope.
157    use super::*;
158
159    #[test]
160    fn test_azbuka_small() {
161        assert_eq!(
162            latin_to_cyrillic("abvgdđežzijklljmnnjoprstćufhcčdžš".to_string()),
163            "абвгдђежзијклљмнњопрстћуфхцчџш"
164        );
165    }
166
167    #[test]
168    fn test_azbuka_big() {
169        assert_eq!(
170            latin_to_cyrillic("ABVGDĐEŽZIJKLLjMNNjOPRSTĆUFHCČDžŠ".to_string()),
171            "АБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШ"
172        );
173    }
174    #[test]
175    fn test_azbuka_small_1000000() {
176        assert_eq!(
177            latin_to_cyrillic(
178                "abvgdđežzijklljmnnjoprstćufhcčdžš"
179                    .repeat(1000000)
180                    .to_string()
181            ),
182            "абвгдђежзијклљмнњопрстћуфхцчџш".repeat(1000000)
183        );
184    }
185
186    #[test]
187    fn test_azbuka_big_1000000() {
188        assert_eq!(
189            latin_to_cyrillic(
190                "ABVGDĐEŽZIJKLLjMNNjOPRSTĆUFHCČDžŠ"
191                    .repeat(1000000)
192                    .to_string()
193            ),
194            "АБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШ".repeat(1000000)
195        );
196    }
197    #[test]
198    fn test_njljdž() {
199        assert_eq!(latin_to_cyrillic("njljdžNjLjDž".to_string()), "њљџЊЉЏ");
200    }
201}