on_off_sequence_output/
morse.rs

1//! Allow morse code output as sequence of states
2
3/// Morse code conversion errors
4#[derive(Debug)]
5pub enum MorseError {
6    UnsupportedCode,
7    SequenceTooLong,
8}
9
10/// String to morse sequence of states
11///
12/// # Arguments
13///
14/// * `input` - String to be translated to morse
15///
16/// # Returns
17///
18/// A result with Ok(tuple) as
19///
20/// * `u128` - a sequence of output states encoded into bits of a u128
21/// * `u16`  - length of the sequence of output states
22///
23/// or Err(MorseError)
24///
25/// # Example
26///
27/// ```rust
28/// use on_off_sequence_output::morse::*;
29///
30/// let (sequence, len) = str_to_morse("SOS").unwrap();
31/// assert_eq!(0b_00_01_01_01_00_0111_0111_0111_00_01_01_01_u128, sequence);
32/// assert_eq!(30_u16, len);
33/// ```
34pub fn str_to_morse(input: &str) -> Result<(u128, u16), MorseError> {
35    let mut sequence = 0b_0_u128;
36    let mut len = 0_u16;
37    for c in input.chars() {
38        let (char_code, char_len) = char_to_morse(c)?;
39        if (len + char_len) > 127 {
40            return Err(MorseError::SequenceTooLong);
41        }
42
43        let mut char_code: u128 = char_code.into(); // convert to expected type
44        char_code = char_code << len;
45        len += char_len;
46        sequence = sequence | char_code;
47    }
48    Ok((sequence, len))
49}
50
51fn char_to_morse(morse_character: char) -> Result<(u32, u16), MorseError> {
52    match morse_character {
53        'A' => Ok((0b_00_0111_01, 8)),
54        'B' => Ok((0b_00_01_01_01_0111, 12)),
55        'C' => Ok((0b_00_01_0111_01_0111, 14)),
56        'D' => Ok((0b_00_01_01_0111, 10)),
57        'E' => Ok((0b_00_01, 4)),
58        'F' => Ok((0b_00_01_0111_01_01, 12)),
59        'G' => Ok((0b_00_01_0111_0111, 12)),
60        'H' => Ok((0b_00_01_01_01_01, 10)),
61        'I' => Ok((0b_00_01_01, 6)),
62        'J' => Ok((0b_00_0111_0111_0111_01, 16)),
63        'K' => Ok((0b_00_0111_01_0111, 12)),
64        'L' => Ok((0b_00_01_01_0111_01, 12)),
65        'M' => Ok((0b_00_0111_0111, 10)),
66        'N' => Ok((0b_00_01_0111, 8)),
67        'O' => Ok((0b_00_0111_0111_0111, 14)),
68        'P' => Ok((0b_00_01_0111_0111_01, 14)),
69        'Q' => Ok((0b_00_0111_01_0111_0111, 16)),
70        'R' => Ok((0b_00_01_0111_01, 10)),
71        'S' => Ok((0b_00_01_01_01, 8)),
72        'T' => Ok((0b_00_0111, 6)),
73        'U' => Ok((0b_00_0111_01_01, 10)),
74        'V' => Ok((0b_00_0111_01_01_01, 12)),
75        'W' => Ok((0b_00_0111_0111_01, 12)),
76        'X' => Ok((0b_00_0111_01_01_0111, 14)),
77        'Y' => Ok((0b_00_0111_0111_01_0111, 16)),
78        'Z' => Ok((0b_00_01_01_0111_0111, 14)),
79        ' ' => Ok((0b_00_00, 4)),
80        '1' => Ok((0b_00_0111_0111_0111_0111_01, 20)),
81        '2' => Ok((0b_00_0111_0111_0111_01_01, 18)),
82        '3' => Ok((0b_00_0111_0111_01_01_01, 16)),
83        '4' => Ok((0b_00_0111_01_01_01_01, 14)),
84        '5' => Ok((0b_00_01_01_01_01_01, 12)),
85        '6' => Ok((0b_00_01_01_01_01_0111, 14)),
86        '7' => Ok((0b_00_01_01_01_0111_0111, 16)),
87        '8' => Ok((0b_00_01_01_0111_0111_0111, 18)),
88        '9' => Ok((0b_00_01_0111_0111_0111_0111, 20)),
89        '0' => Ok((0b_00_0111_0111_0111_0111_0111, 22)),
90        _ => Err(MorseError::UnsupportedCode),
91    }
92}
93
94#[cfg(test)]
95mod tests;