1#![allow(unused_assignments)]
2use std::cmp::Ordering;
3use serde_json::Value;
4use stringplus::StringPlus;
5
6pub struct PhoneticParser {
8    patterns: Vec<Value>,
9    vowel: String,
10    consonant: String,
11    numbers: String,
12    case_sensitive: String,
13    max_pattern_len: usize,
14}
15
16impl PhoneticParser {
17    pub fn new(rule: &Value) -> PhoneticParser {
21        PhoneticParser {
22            patterns: rule["patterns"].as_array().unwrap().clone(),
23            vowel: rule["vowel"].as_str().unwrap().to_string(),
24            consonant: rule["consonant"].as_str().unwrap().to_string(),
25            numbers: rule["number"].as_str().unwrap().to_string(),
26            case_sensitive: rule["casesensitive"].as_str().unwrap().to_string(),
27            max_pattern_len: rule["patterns"][0]["find"].as_str().unwrap().len(),
28        }
29    }
30
31    pub fn convert(&self, input: &str) -> String {
33        let fixed = self.fix_string(input);
34        let len = fixed.len();
35        let mut output = String::with_capacity(len * 3);
36
37        let mut cur = 0;
38        while cur < len {
39            let start = cur as i32;
40            let mut end: i32 = 0;
41            let mut matched = false;
42
43            for chunk_len in (1..=self.max_pattern_len).rev() {
44                end = start + chunk_len as i32;
45                if end <= len as i32 {
46                    let chunk = fixed.substring(start as usize, chunk_len as usize);
47
48                    let mut left: i32 = 0;
50                    let mut right = self.patterns.len() as i32 - 1;
51                    let mut mid: i32 = 0;
52                    while right >= left {
53                        mid = (right + left) / 2;
54                        let pattern = &self.patterns[mid as usize];
55                        let find = pattern["find"].as_str().unwrap();
56                        if find == chunk {
57                            let rules = pattern["rules"].as_array().unwrap();
58                            if !rules.is_empty() {
59                                for rule in rules {
60                                    let mut replace = true;
61                                    let mut chk = 0;
62                                    let matches = rule["matches"].as_array().unwrap();
63                                    for _match in matches {
64                                        let value = _match["value"].as_str().unwrap_or_default();
65                                        let _type = _match["type"].as_str().unwrap();
66                                        let mut scope = _match["scope"].as_str().unwrap();
67                                        let mut is_negative = false;
68
69                                        if &scope[0..1] == "!" {
71                                            is_negative = true;
72                                            scope = &scope[1..];
73                                        }
74
75                                        if _type == "suffix" {
76                                            chk = end;
77                                        } else {
78                                            chk = start - 1;
79                                        }
80
81                                        match scope {
83                                            "punctuation" => if ((chk < 0 && (_type == "prefix"))
84                                                || (chk >= len as i32 && (_type == "suffix"))
85                                                || self.is_punctuation(fixed.at(chk as usize)))
86                                                == is_negative
87                                            {
88                                                replace = false;
89                                                break;
90                                            },
91                                            "vowel" => if (((chk >= 0 && (_type == "prefix"))
92                                                || (chk < len as i32 && (_type == "suffix")))
93                                                && self.is_vowel(fixed.at(chk as usize)))
94                                                == is_negative
95                                            {
96                                                replace = false;
97                                                break;
98                                            },
99
100                                            "consonant" => if (((chk >= 0 && (_type == "prefix"))
101                                                || (chk < len as i32 && (_type == "suffix")))
102                                                && self.is_consonant(fixed.at(chk as usize)))
103                                                == is_negative
104                                            {
105                                                replace = false;
106                                                break;
107                                            },
108
109                                            "number" => if (((chk >= 0 && (_type == "prefix"))
110                                                || (chk < len as i32 && (_type == "suffix")))
111                                                && self.is_number(fixed.at(chk as usize)))
112                                                == is_negative
113                                            {
114                                                replace = false;
115                                                break;
116                                            },
117
118                                            "exact" => {
119                                                let mut s: i32 = 0;
120                                                let mut e: i32 = 0;
121                                                if _type == "suffix" {
122                                                    s = end;
123                                                    e = end + value.len() as i32;
124                                                } else {
125                                                    s = start - value.len() as i32;
127                                                    e = start;
128                                                }
129                                                if !self.is_exact(value, &fixed, s, e, is_negative)
130                                                {
131                                                    replace = false;
132                                                    break;
133                                                }
134                                            }
135                                            _ => panic!("Unknown scope"),
136                                        };
137                                    }
138
139                                    if replace {
140                                        output += rule["replace"].as_str().unwrap();
141                                        cur = (end - 1) as usize;
142                                        matched = true;
143                                        break;
144                                    }
145                                }
146                            }
147
148                            if matched {
149                                break;
150                            }
151
152                            output += pattern["replace"].as_str().unwrap();
154                            cur = (end - 1) as usize;
155                            matched = true;
156                            break;
157                        } else if find.len() > chunk.len()
158                            || (find.len() == chunk.len() && find.cmp(&chunk) == Ordering::Less)
159                        {
160                            left = mid + 1;
161                        } else {
162                            right = mid - 1;
163                        }
164                    }
165                    if matched {
166                        break;
167                    }
168                }
169            }
170
171            if !matched {
172                output += &fixed[cur..cur + 1];
173            }
174            cur += 1;
175        }
176
177        output
178    }
179
180    fn fix_string(&self, string: &str) -> String {
181        string
182            .chars()
183            .map(|character| {
184                if self.is_case_sensitive(character) {
185                    character
186                } else {
187                    character.to_ascii_lowercase()
188                }
189            })
190            .collect()
191    }
192
193    fn is_vowel(&self, string: &str) -> bool {
194        self.vowel.contains(&string.to_ascii_lowercase())
195    }
196
197    fn is_consonant(&self, string: &str) -> bool {
198        self.consonant.contains(&string.to_ascii_lowercase())
199    }
200
201    fn is_case_sensitive(&self, character: char) -> bool {
202        self.case_sensitive
203            .contains(character.to_ascii_lowercase())
204    }
205
206    fn is_number(&self, character: &str) -> bool {
207        self.numbers.contains(character)
208    }
209
210    fn is_exact(&self, needle: &str, heystack: &str, start: i32, end: i32, not: bool) -> bool {
211        let len = end - start;
212        (start >= 0 && end < heystack.len() as i32
213            && (heystack.substring(start as usize, len as usize) == needle)) != not
214    }
215
216    fn is_punctuation(&self, character: &str) -> bool {
217        !(self.is_vowel(character) || self.is_consonant(character))
218    }
219}
220
221#[cfg(test)]
222mod tests {
223    use serde_json;
224    use super::PhoneticParser;
225
226    #[test]
227    fn test_helpers() {
228        let json = serde_json::from_str(include_str!("AvroPhonetic.json")).unwrap();
229        let parser = PhoneticParser::new(&json);
230
231        assert!(parser.is_vowel("A"));
232        assert_eq!(parser.is_vowel("b"), false);
233        assert!(parser.is_consonant("B"));
234        assert_eq!(parser.is_consonant("e"), false);
235        assert_eq!(parser.fix_string("ODEr AMAr"), "ODer amar");
236        assert!(parser.is_number("1"));
237    }
238
239    #[test]
240    fn test_basic() {
241        let json = serde_json::from_str(include_str!("AvroPhonetic.json")).unwrap();
242        let parser = PhoneticParser::new(&json);
243
244        assert_eq!(parser.convert("bhl"), "ভ্ল");
245        assert_eq!(parser.convert("bj"), "ব্জ");
246        assert_eq!(parser.convert("bd"), "ব্দ");
247        assert_eq!(parser.convert("bb"), "ব্ব");
248        assert_eq!(parser.convert("bl"), "ব্ল");
249        assert_eq!(parser.convert("bh"), "ভ");
250        assert_eq!(parser.convert("vl"), "ভ্ল");
251        assert_eq!(parser.convert("b"), "ব");
252        assert_eq!(parser.convert("v"), "ভ");
253        assert_eq!(parser.convert("cNG"), "চ্ঞ");
254        assert_eq!(parser.convert("cch"), "চ্ছ");
255        assert_eq!(parser.convert("cc"), "চ্চ");
256        assert_eq!(parser.convert("ch"), "ছ");
257        assert_eq!(parser.convert("c"), "চ");
258        assert_eq!(parser.convert("dhn"), "ধ্ন");
259        assert_eq!(parser.convert("dhm"), "ধ্ম");
260        assert_eq!(parser.convert("dgh"), "দ্ঘ");
261        assert_eq!(parser.convert("ddh"), "দ্ধ");
262        assert_eq!(parser.convert("dbh"), "দ্ভ");
263        assert_eq!(parser.convert("dv"), "দ্ভ");
264        assert_eq!(parser.convert("dm"), "দ্ম");
265        assert_eq!(parser.convert("DD"), "ড্ড");
266        assert_eq!(parser.convert("Dh"), "ঢ");
267        assert_eq!(parser.convert("dh"), "ধ");
268        assert_eq!(parser.convert("dg"), "দ্গ");
269        assert_eq!(parser.convert("dd"), "দ্দ");
270        assert_eq!(parser.convert("D"), "ড");
271        assert_eq!(parser.convert("d"), "দ");
272        assert_eq!(parser.convert("..."), "...");
273        assert_eq!(parser.convert(".`"), ".");
274        assert_eq!(parser.convert(".."), "।।");
275        assert_eq!(parser.convert("."), "।");
276        assert_eq!(parser.convert("ghn"), "ঘ্ন");
277        assert_eq!(parser.convert("Ghn"), "ঘ্ন");
278        assert_eq!(parser.convert("gdh"), "গ্ধ");
279        assert_eq!(parser.convert("gN"), "গ্ণ");
280        assert_eq!(parser.convert("GN"), "গ্ণ");
281        assert_eq!(parser.convert("gn"), "গ্ন");
282        assert_eq!(parser.convert("gm"), "গ্ম");
283        assert_eq!(parser.convert("Gm"), "গ্ম");
284        assert_eq!(parser.convert("gl"), "গ্ল");
285        assert_eq!(parser.convert("Gl"), "গ্ল");
286        assert_eq!(parser.convert("gg"), "জ্ঞ");
287        assert_eq!(parser.convert("GG"), "জ্ঞ");
288        assert_eq!(parser.convert("Gg"), "জ্ঞ");
289        assert_eq!(parser.convert("gG"), "জ্ঞ");
290        assert_eq!(parser.convert("gh"), "ঘ");
291        assert_eq!(parser.convert("Gh"), "ঘ");
292        assert_eq!(parser.convert("g"), "গ");
293        assert_eq!(parser.convert("hN"), "হ্ণ");
294        assert_eq!(parser.convert("hn"), "হ্ন");
295        assert_eq!(parser.convert("hm"), "হ্ম");
296        assert_eq!(parser.convert("hl"), "হ্ল");
297        assert_eq!(parser.convert("h"), "হ");
298        assert_eq!(parser.convert("jjh"), "জ্ঝ");
299        assert_eq!(parser.convert("jNG"), "জ্ঞ");
300        assert_eq!(parser.convert("jh"), "ঝ");
301        assert_eq!(parser.convert("jj"), "জ্জ");
302        assert_eq!(parser.convert("j"), "জ");
303        assert_eq!(parser.convert("J"), "জ");
304        assert_eq!(parser.convert("kkhN"), "ক্ষ্ণ");
305        assert_eq!(parser.convert("kShN"), "ক্ষ্ণ");
306        assert_eq!(parser.convert("kkhm"), "ক্ষ্ম");
307        assert_eq!(parser.convert("kShm"), "ক্ষ্ম");
308        assert_eq!(parser.convert("kxN"), "ক্ষ্ণ");
309        assert_eq!(parser.convert("kxm"), "ক্ষ্ম");
310        assert_eq!(parser.convert("kkh"), "ক্ষ");
311        assert_eq!(parser.convert("kSh"), "ক্ষ");
312        assert_eq!(parser.convert("ksh"), "কশ");
313        assert_eq!(parser.convert("kx"), "ক্ষ");
314        assert_eq!(parser.convert("kk"), "ক্ক");
315        assert_eq!(parser.convert("kT"), "ক্ট");
316        assert_eq!(parser.convert("kt"), "ক্ত");
317        assert_eq!(parser.convert("kl"), "ক্ল");
318        assert_eq!(parser.convert("ks"), "ক্স");
319        assert_eq!(parser.convert("kh"), "খ");
320        assert_eq!(parser.convert("k"), "ক");
321        assert_eq!(parser.convert("lbh"), "ল্ভ");
322        assert_eq!(parser.convert("ldh"), "ল্ধ");
323        assert_eq!(parser.convert("lkh"), "লখ");
324        assert_eq!(parser.convert("lgh"), "লঘ");
325        assert_eq!(parser.convert("lph"), "লফ");
326        assert_eq!(parser.convert("lk"), "ল্ক");
327        assert_eq!(parser.convert("lg"), "ল্গ");
328        assert_eq!(parser.convert("lT"), "ল্ট");
329        assert_eq!(parser.convert("lD"), "ল্ড");
330        assert_eq!(parser.convert("lp"), "ল্প");
331        assert_eq!(parser.convert("lv"), "ল্ভ");
332        assert_eq!(parser.convert("lm"), "ল্ম");
333        assert_eq!(parser.convert("ll"), "ল্ল");
334        assert_eq!(parser.convert("lb"), "ল্ব");
335        assert_eq!(parser.convert("l"), "ল");
336        assert_eq!(parser.convert("mth"), "ম্থ");
337        assert_eq!(parser.convert("mph"), "ম্ফ");
338        assert_eq!(parser.convert("mbh"), "ম্ভ");
339        assert_eq!(parser.convert("mpl"), "মপ্ল");
340        assert_eq!(parser.convert("mn"), "ম্ন");
341        assert_eq!(parser.convert("mp"), "ম্প");
342        assert_eq!(parser.convert("mv"), "ম্ভ");
343        assert_eq!(parser.convert("mm"), "ম্ম");
344        assert_eq!(parser.convert("ml"), "ম্ল");
345        assert_eq!(parser.convert("mb"), "ম্ব");
346        assert_eq!(parser.convert("mf"), "ম্ফ");
347        assert_eq!(parser.convert("m"), "ম");
348        assert_eq!(parser.convert("0"), "০");
349        assert_eq!(parser.convert("1"), "১");
350        assert_eq!(parser.convert("2"), "২");
351        assert_eq!(parser.convert("3"), "৩");
352        assert_eq!(parser.convert("4"), "৪");
353        assert_eq!(parser.convert("5"), "৫");
354        assert_eq!(parser.convert("6"), "৬");
355        assert_eq!(parser.convert("7"), "৭");
356        assert_eq!(parser.convert("8"), "৮");
357        assert_eq!(parser.convert("9"), "৯");
358        assert_eq!(parser.convert("NgkSh"), "ঙ্ক্ষ");
359        assert_eq!(parser.convert("Ngkkh"), "ঙ্ক্ষ");
360        assert_eq!(parser.convert("NGch"), "ঞ্ছ");
361        assert_eq!(parser.convert("Nggh"), "ঙ্ঘ");
362        assert_eq!(parser.convert("Ngkh"), "ঙ্খ");
363        assert_eq!(parser.convert("NGjh"), "ঞ্ঝ");
364        assert_eq!(parser.convert("ngOU"), "ঙ্গৌ");
365        assert_eq!(parser.convert("ngOI"), "ঙ্গৈ");
366        assert_eq!(parser.convert("Ngkx"), "ঙ্ক্ষ");
367        assert_eq!(parser.convert("NGc"), "ঞ্চ");
368        assert_eq!(parser.convert("nch"), "ঞ্ছ");
369        assert_eq!(parser.convert("njh"), "ঞ্ঝ");
370        assert_eq!(parser.convert("ngh"), "ঙ্ঘ");
371        assert_eq!(parser.convert("Ngk"), "ঙ্ক");
372        assert_eq!(parser.convert("Ngx"), "ঙ্ষ");
373        assert_eq!(parser.convert("Ngg"), "ঙ্গ");
374        assert_eq!(parser.convert("Ngm"), "ঙ্ম");
375        assert_eq!(parser.convert("NGj"), "ঞ্জ");
376        assert_eq!(parser.convert("ndh"), "ন্ধ");
377        assert_eq!(parser.convert("nTh"), "ন্ঠ");
378        assert_eq!(parser.convert("NTh"), "ণ্ঠ");
379        assert_eq!(parser.convert("nth"), "ন্থ");
380        assert_eq!(parser.convert("nkh"), "ঙ্খ");
381        assert_eq!(parser.convert("ngo"), "ঙ্গ");
382        assert_eq!(parser.convert("nga"), "ঙ্গা");
383        assert_eq!(parser.convert("ngi"), "ঙ্গি");
384        assert_eq!(parser.convert("ngI"), "ঙ্গী");
385        assert_eq!(parser.convert("ngu"), "ঙ্গু");
386        assert_eq!(parser.convert("ngU"), "ঙ্গূ");
387        assert_eq!(parser.convert("nge"), "ঙ্গে");
388        assert_eq!(parser.convert("ngO"), "ঙ্গো");
389        assert_eq!(parser.convert("NDh"), "ণ্ঢ");
390        assert_eq!(parser.convert("nsh"), "নশ");
391        assert_eq!(parser.convert("Ngr"), "ঙর");
392        assert_eq!(parser.convert("NGr"), "ঞর");
393        assert_eq!(parser.convert("ngr"), "ংর");
394        assert_eq!(parser.convert("nj"), "ঞ্জ");
395        assert_eq!(parser.convert("Ng"), "ঙ");
396        assert_eq!(parser.convert("NG"), "ঞ");
397        assert_eq!(parser.convert("nk"), "ঙ্ক");
398        assert_eq!(parser.convert("ng"), "ং");
399        assert_eq!(parser.convert("nn"), "ন্ন");
400        assert_eq!(parser.convert("NN"), "ণ্ণ");
401        assert_eq!(parser.convert("Nn"), "ণ্ন");
402        assert_eq!(parser.convert("nm"), "ন্ম");
403        assert_eq!(parser.convert("Nm"), "ণ্ম");
404        assert_eq!(parser.convert("nd"), "ন্দ");
405        assert_eq!(parser.convert("nT"), "ন্ট");
406        assert_eq!(parser.convert("NT"), "ণ্ট");
407        assert_eq!(parser.convert("nD"), "ন্ড");
408        assert_eq!(parser.convert("ND"), "ণ্ড");
409        assert_eq!(parser.convert("nt"), "ন্ত");
410        assert_eq!(parser.convert("ns"), "ন্স");
411        assert_eq!(parser.convert("nc"), "ঞ্চ");
412        assert_eq!(parser.convert("n"), "ন");
413        assert_eq!(parser.convert("N"), "ণ");
414        assert_eq!(parser.convert("OI`"), "ৈ");
415        assert_eq!(parser.convert("OU`"), "ৌ");
416        assert_eq!(parser.convert("O`"), "ো");
417        assert_eq!(parser.convert("OI"), "ঐ");
418        assert_eq!(parser.convert("kOI"), "কৈ");
419        assert_eq!(parser.convert(" OI"), " ঐ");
420        assert_eq!(parser.convert("(OI"), "(ঐ");
421        assert_eq!(parser.convert(".OI"), "।ঐ");
422        assert_eq!(parser.convert("OU"), "ঔ");
423        assert_eq!(parser.convert("kOU"), "কৌ");
424        assert_eq!(parser.convert(" OU"), " ঔ");
425        assert_eq!(parser.convert("-OU"), "-ঔ");
426        assert_eq!(parser.convert(",,OU"), "্ঔ");
427        assert_eq!(parser.convert("O"), "ও");
428        assert_eq!(parser.convert("pO"), "পো");
429        assert_eq!(parser.convert(" O"), " ও");
430        assert_eq!(parser.convert("iO"), "ইও");
431        assert_eq!(parser.convert("`O"), "ও");
432        assert_eq!(parser.convert("phl"), "ফ্ল");
433        assert_eq!(parser.convert("pT"), "প্ট");
434        assert_eq!(parser.convert("pt"), "প্ত");
435        assert_eq!(parser.convert("pn"), "প্ন");
436        assert_eq!(parser.convert("pp"), "প্প");
437        assert_eq!(parser.convert("pl"), "প্ল");
438        assert_eq!(parser.convert("ps"), "প্স");
439        assert_eq!(parser.convert("ph"), "ফ");
440        assert_eq!(parser.convert("fl"), "ফ্ল");
441        assert_eq!(parser.convert("f"), "ফ");
442        assert_eq!(parser.convert("p"), "প");
443        assert_eq!(parser.convert("rri`"), "ৃ");
444        assert_eq!(parser.convert("rri"), "ঋ");
445        assert_eq!(parser.convert("krri"), "কৃ");
446        assert_eq!(parser.convert("Irri"), "ঈঋ");
447        assert_eq!(parser.convert("^rri"), "ঁঋ");
448        assert_eq!(parser.convert(":rri"), "ঃঋ");
449        assert_eq!(parser.convert("rZ"), "র্য");
450        assert_eq!(parser.convert("krZ"), "ক্র্য");
451        assert_eq!(parser.convert("rrZ"), "রর্য");
452        assert_eq!(parser.convert("yrZ"), "ইয়র্য");
453        assert_eq!(parser.convert("wrZ"), "ওর্য");
454        assert_eq!(parser.convert("xrZ"), "এক্সর্য");
455        assert_eq!(parser.convert("irZ"), "ইর্য");
456        assert_eq!(parser.convert("-rZ"), "-র্য");
457        assert_eq!(parser.convert("rrrZ"), "ররর্য");
458        assert_eq!(parser.convert("ry"), "র্য");
459        assert_eq!(parser.convert("qry"), "ক্র্য");
460        assert_eq!(parser.convert("rry"), "রর্য");
461        assert_eq!(parser.convert("yry"), "ইয়র্য");
462        assert_eq!(parser.convert("wry"), "ওর্য");
463        assert_eq!(parser.convert("xry"), "এক্সর্য");
464        assert_eq!(parser.convert("0ry"), "০র্য");
465        assert_eq!(parser.convert("rrrry"), "রররর্য");
466        assert_eq!(parser.convert("Rry"), "ড়্র্য");
467        assert_eq!(parser.convert("rr"), "রর");
468        assert_eq!(parser.convert("arr"), "আরর");
469        assert_eq!(parser.convert("arrk"), "আর্ক");
470        assert_eq!(parser.convert("arra"), "আররা");
471        assert_eq!(parser.convert("arr"), "আরর");
472        assert_eq!(parser.convert("arr!"), "আরর!");
473        assert_eq!(parser.convert("krr"), "ক্রর");
474        assert_eq!(parser.convert("krra"), "ক্ররা");
475        assert_eq!(parser.convert("Rg"), "ড়্গ");
476        assert_eq!(parser.convert("Rh"), "ঢ়");
477        assert_eq!(parser.convert("R"), "ড়");
478        assert_eq!(parser.convert("r"), "র");
479        assert_eq!(parser.convert("or"), "অর");
480        assert_eq!(parser.convert("mr"), "ম্র");
481        assert_eq!(parser.convert("1r"), "১র");
482        assert_eq!(parser.convert("+r"), "+র");
483        assert_eq!(parser.convert("rr"), "রর");
484        assert_eq!(parser.convert("yr"), "ইয়র");
485        assert_eq!(parser.convert("wr"), "ওর");
486        assert_eq!(parser.convert("xr"), "এক্সর");
487        assert_eq!(parser.convert("zr"), "য্র");
488        assert_eq!(parser.convert("mri"), "ম্রি");
489        assert_eq!(parser.convert("shch"), "শ্ছ");
490        assert_eq!(parser.convert("ShTh"), "ষ্ঠ");
491        assert_eq!(parser.convert("Shph"), "ষ্ফ");
492        assert_eq!(parser.convert("Sch"), "শ্ছ");
493        assert_eq!(parser.convert("skl"), "স্ক্ল");
494        assert_eq!(parser.convert("skh"), "স্খ");
495        assert_eq!(parser.convert("sth"), "স্থ");
496        assert_eq!(parser.convert("sph"), "স্ফ");
497        assert_eq!(parser.convert("shc"), "শ্চ");
498        assert_eq!(parser.convert("sht"), "শ্ত");
499        assert_eq!(parser.convert("shn"), "শ্ন");
500        assert_eq!(parser.convert("shm"), "শ্ম");
501        assert_eq!(parser.convert("shl"), "শ্ল");
502        assert_eq!(parser.convert("Shk"), "ষ্ক");
503        assert_eq!(parser.convert("ShT"), "ষ্ট");
504        assert_eq!(parser.convert("ShN"), "ষ্ণ");
505        assert_eq!(parser.convert("Shp"), "ষ্প");
506        assert_eq!(parser.convert("Shf"), "ষ্ফ");
507        assert_eq!(parser.convert("Shm"), "ষ্ম");
508        assert_eq!(parser.convert("spl"), "স্প্ল");
509        assert_eq!(parser.convert("sk"), "স্ক");
510        assert_eq!(parser.convert("Sc"), "শ্চ");
511        assert_eq!(parser.convert("sT"), "স্ট");
512        assert_eq!(parser.convert("st"), "স্ত");
513        assert_eq!(parser.convert("sn"), "স্ন");
514        assert_eq!(parser.convert("sp"), "স্প");
515        assert_eq!(parser.convert("sf"), "স্ফ");
516        assert_eq!(parser.convert("sm"), "স্ম");
517        assert_eq!(parser.convert("sl"), "স্ল");
518        assert_eq!(parser.convert("sh"), "শ");
519        assert_eq!(parser.convert("Sc"), "শ্চ");
520        assert_eq!(parser.convert("St"), "শ্ত");
521        assert_eq!(parser.convert("Sn"), "শ্ন");
522        assert_eq!(parser.convert("Sm"), "শ্ম");
523        assert_eq!(parser.convert("Sl"), "শ্ল");
524        assert_eq!(parser.convert("Sh"), "ষ");
525        assert_eq!(parser.convert("s"), "স");
526        assert_eq!(parser.convert("S"), "শ");
527        assert_eq!(parser.convert("oo"), "উ");
528        assert_eq!(parser.convert("OO"), "ওও");
529        assert_eq!(parser.convert("oo`"), "ু");
530        assert_eq!(parser.convert("koo"), "কু");
531        assert_eq!(parser.convert("ooo"), "উঅ");
532        assert_eq!(parser.convert("!oo"), "!উ");
533        assert_eq!(parser.convert("!ooo"), "!উঅ");
534        assert_eq!(parser.convert("aoo"), "আউ");
535        assert_eq!(parser.convert("oop"), "উপ");
536        assert_eq!(parser.convert("ooo`"), "উ");
537        assert_eq!(parser.convert("o`"), "");
538        assert_eq!(parser.convert("oZ"), "অ্য");
539        assert_eq!(parser.convert("oY"), "অয়");
540        assert_eq!(parser.convert("o"), "অ");
541        assert_eq!(parser.convert("!o"), "!অ");
542        assert_eq!(parser.convert("^o"), "ঁঅ");
543        assert_eq!(parser.convert("*o"), "*অ");
544        assert_eq!(parser.convert("io"), "ইও");
545        assert_eq!(parser.convert("yo"), "ইয়");
546        assert_eq!(parser.convert("no"), "ন");
547        assert_eq!(parser.convert("tth"), "ত্থ");
548        assert_eq!(parser.convert("t``"), "ৎ");
549        assert_eq!(parser.convert("`t``"), "ৎ");
550        assert_eq!(parser.convert("t``t``"), "ৎৎ");
551        assert_eq!(parser.convert("t```"), "ৎ");
552        assert_eq!(parser.convert("TT"), "ট্ট");
553        assert_eq!(parser.convert("Tm"), "ট্ম");
554        assert_eq!(parser.convert("Th"), "ঠ");
555        assert_eq!(parser.convert("tn"), "ত্ন");
556        assert_eq!(parser.convert("tm"), "ত্ম");
557        assert_eq!(parser.convert("th"), "থ");
558        assert_eq!(parser.convert("tt"), "ত্ত");
559        assert_eq!(parser.convert("T"), "ট");
560        assert_eq!(parser.convert("t"), "ত");
561        assert_eq!(parser.convert("aZ"), "অ্যা");
562        assert_eq!(parser.convert("aaZ"), "আঅ্যা");
563        assert_eq!(parser.convert("AZ"), "অ্যা");
564        assert_eq!(parser.convert("a`"), "া");
565        assert_eq!(parser.convert("a``"), "া");
566        assert_eq!(parser.convert("ka`"), "কা");
567        assert_eq!(parser.convert("A`"), "া");
568        assert_eq!(parser.convert("a"), "আ");
569        assert_eq!(parser.convert("`a"), "আ");
570        assert_eq!(parser.convert("k`a"), "কআ");
571        assert_eq!(parser.convert("ia"), "ইয়া");
572        assert_eq!(parser.convert("aaaa`"), "আআআা");
573        assert_eq!(parser.convert("i`"), "ি");
574        assert_eq!(parser.convert("i"), "ই");
575        assert_eq!(parser.convert("`i"), "ই");
576        assert_eq!(parser.convert("hi"), "হি");
577        assert_eq!(parser.convert("ih"), "ইহ");
578        assert_eq!(parser.convert("i`h"), "িহ");
579        assert_eq!(parser.convert("I`"), "ী");
580        assert_eq!(parser.convert("I"), "ঈ");
581        assert_eq!(parser.convert("cI"), "চী");
582        assert_eq!(parser.convert("Ix"), "ঈক্স");
583        assert_eq!(parser.convert("II"), "ঈঈ");
584        assert_eq!(parser.convert("0I"), "০ঈ");
585        assert_eq!(parser.convert("oI"), "অঈ");
586        assert_eq!(parser.convert("u`"), "ু");
587        assert_eq!(parser.convert("u"), "উ");
588        assert_eq!(parser.convert("ku"), "কু");
589        assert_eq!(parser.convert("uk"), "উক");
590        assert_eq!(parser.convert("uu"), "উউ");
591        assert_eq!(parser.convert("iu"), "ইউ");
592        assert_eq!(parser.convert("&u"), "&উ");
593        assert_eq!(parser.convert("u&"), "উ&");
594        assert_eq!(parser.convert("U`"), "ূ");
595        assert_eq!(parser.convert("U"), "ঊ");
596        assert_eq!(parser.convert("yU"), "ইয়ূ");
597        assert_eq!(parser.convert("Uy"), "ঊয়");
598        assert_eq!(parser.convert("^U"), "ঁঊ");
599        assert_eq!(parser.convert("U^"), "ঊঁ");
600        assert_eq!(parser.convert("EE"), "ঈ");
601        assert_eq!(parser.convert("ee"), "ঈ");
602        assert_eq!(parser.convert("Ee"), "ঈ");
603        assert_eq!(parser.convert("eE"), "ঈ");
604        assert_eq!(parser.convert("ee`"), "ী");
605        assert_eq!(parser.convert("kee"), "কী");
606        assert_eq!(parser.convert("eek"), "ঈক");
607        assert_eq!(parser.convert("0ee"), "০ঈ");
608        assert_eq!(parser.convert("ee8"), "ঈ৮");
609        assert_eq!(parser.convert("(ee)"), "(ঈ)");
610        assert_eq!(parser.convert("e`"), "ে");
611        assert_eq!(parser.convert("e"), "এ");
612        assert_eq!(parser.convert("ke"), "কে");
613        assert_eq!(parser.convert("we"), "ওয়ে");
614        assert_eq!(parser.convert("#e#"), "#এ#");
615        assert_eq!(parser.convert("`e`"), "ে");
616        assert_eq!(parser.convert("z"), "য");
617        assert_eq!(parser.convert("Z"), "্য");
618        assert_eq!(parser.convert("rZ"), "র্য");
619        assert_eq!(parser.convert("kZS"), "ক্যশ");
620        assert_eq!(parser.convert("y"), "ইয়");
621        assert_eq!(parser.convert("oy"), "অয়");
622        assert_eq!(parser.convert("ky"), "ক্য");
623        assert_eq!(parser.convert("ya"), "ইয়া");
624        assert_eq!(parser.convert("yaa"), "ইয়াআ");
625        assert_eq!(parser.convert("Y"), "য়");
626        assert_eq!(parser.convert("YY"), "য়য়");
627        assert_eq!(parser.convert("iY"), "ইয়");
628        assert_eq!(parser.convert("kY"), "কয়");
629        assert_eq!(parser.convert("q"), "ক");
630        assert_eq!(parser.convert("Q"), "ক");
631        assert_eq!(parser.convert("w"), "ও");
632        assert_eq!(parser.convert("wa"), "ওয়া");
633        assert_eq!(parser.convert("-wa-"), "-ওয়া-");
634        assert_eq!(parser.convert("woo"), "ওয়ু");
635        assert_eq!(parser.convert("wre"), "ওরে");
636        assert_eq!(parser.convert("kw"), "ক্ব");
637        assert_eq!(parser.convert("x"), "এক্স");
638        assert_eq!(parser.convert("ex"), "এক্স");
639        assert_eq!(parser.convert("bx"), "বক্স");
640        assert_eq!(parser.convert(":`"), ":");
641        assert_eq!(parser.convert(":"), "ঃ");
642        assert_eq!(parser.convert("^`"), "^");
643        assert_eq!(parser.convert("^"), "ঁ");
644        assert_eq!(parser.convert("k^"), "কঁ");
645        assert_eq!(parser.convert("k^i"), "কঁই");
646        assert_eq!(parser.convert("ki^"), "কিঁ");
647        assert_eq!(parser.convert(",,"), "্");
648        assert_eq!(parser.convert(",,,"), "্,");
649        assert_eq!(parser.convert(",,`,"), "্,");
650        assert_eq!(parser.convert("`,,"), "্");
651        assert_eq!(parser.convert(",`,"), ",,");
652        assert_eq!(parser.convert("$"), "৳");
653        assert_eq!(parser.convert("`"), "");
654        assert_eq!(parser.convert("bdh"), "ব্ধ");
655    }
656
657    #[test]
658    fn test_sentence() {
659        let json = serde_json::from_str(include_str!("AvroPhonetic.json")).unwrap();
660        let parser = PhoneticParser::new(&json);
661
662        assert_eq!(parser.convert("ami banglay gan gai"),  "আমি বাংলায় গান গাই");
663        assert_eq!(parser.convert("amader valObasa hoye gel ghas, kheye gel goru ar diye gelo ba^sh"),  "আমাদের ভালোবাসা হয়ে গেল ঘাস, খেয়ে গেল গরু আর দিয়ে গেল বাঁশ");
664    }
665}