munemo_rs/
decoder.rs

1use crate::constants::*;
2
3pub fn decode(mut code: &str) -> Option<i64> {
4  let mut value: i64 = 0;
5  let negative_factor = if code.starts_with(NEGATIVE_SYLLABLE) {
6    code = &code[NEGATIVE_SYLLABLE.len()..];
7    -1
8  } else {
9    1
10  };
11
12  while code.len() > 0 {
13    match SYLLABLES
14      .iter()
15      .position(|&syllable| code.starts_with(syllable))
16    {
17      Some(index) => {
18        value *= SYLLABLES.len() as i64;
19        value += index as i64;
20        code = &code[SYLLABLES[index].len()..];
21      }
22      None => return None,
23    };
24  }
25  Some(value * negative_factor)
26}
27
28#[cfg(test)]
29mod tests {
30  use super::*;
31  use rand::Rng;
32
33  #[test]
34  fn single_syllable() {
35    let units = rand::thread_rng().gen_range(0, SYLLABLES.len());
36    let value = units as i64;
37
38    assert_eq!(decode(SYLLABLES[units]).unwrap(), value);
39  }
40
41  #[test]
42  fn unknown_syllable() {
43    assert_eq!(decode("aa"), None);
44  }
45
46  #[test]
47  fn many_tens() {
48    let tens = rand::thread_rng().gen_range(1, SYLLABLES.len());
49    let units = rand::thread_rng().gen_range(0, SYLLABLES.len());
50    let value = (tens * SYLLABLES.len() + units) as i64;
51
52    assert_eq!(
53      decode(&[SYLLABLES[tens], SYLLABLES[units]].concat()).unwrap(),
54      value
55    );
56  }
57
58  #[test]
59  fn many_hundreds() {
60    let hundreds = rand::thread_rng().gen_range(1, SYLLABLES.len());
61    let tens = rand::thread_rng().gen_range(0, SYLLABLES.len());
62    let units = rand::thread_rng().gen_range(0, SYLLABLES.len());
63    let value =
64      (hundreds * SYLLABLES.len() * SYLLABLES.len() + tens * SYLLABLES.len() + units) as i64;
65
66    assert_eq!(
67      decode(&[SYLLABLES[hundreds], SYLLABLES[tens], SYLLABLES[units]].concat()).unwrap(),
68      value
69    );
70  }
71
72  #[test]
73  fn negative() {
74    let units = rand::thread_rng().gen_range(0, SYLLABLES.len());
75    let value = (units as i64) * -1;
76
77    assert_eq!(
78      decode(&[NEGATIVE_SYLLABLE, SYLLABLES[units]].concat()).unwrap(),
79      value
80    );
81  }
82}