From ba8eac6bde31aae880fc72c5ef9e1da778d349c3 Mon Sep 17 00:00:00 2001 From: ghaisan Date: Fri, 4 Oct 2024 01:12:51 +0700 Subject: [PATCH] Added decoding from morse text --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 2 +- src/lib.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 110 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b096eec..d5cd226 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" [[package]] name = "morse_rs" -version = "0.1.0" +version = "0.1.1" dependencies = [ "hound", ] diff --git a/Cargo.toml b/Cargo.toml index 6e6b65b..373cd0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "morse_rs" description = "A simple morse code translator, with the abilty to write to WAV files using Hound." license = "MIT" -version = "0.1.0" +version = "0.1.1" edition = "2021" [dependencies] diff --git a/README.md b/README.md index 08016dc..681547c 100644 --- a/README.md +++ b/README.md @@ -32,5 +32,5 @@ fn main() { ``` ## TODO -- Decode morse from string and sound +- Decode morse from sound - Add proper rust like error return types diff --git a/src/lib.rs b/src/lib.rs index 938acc1..925f521 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ fn write_freq(writer: &mut WavWriter>, freq: f32, durati } pub fn to_morse(text: &str) -> String { - let morse_map: HashMap = HashMap::from([ + let char_to_morse: HashMap = HashMap::from([ ('a', ".-"), ('b', "-..."), ('c', "-.-."), @@ -67,16 +67,29 @@ pub fn to_morse(text: &str) -> String { let code = text.to_lowercase(); let mut ret = String::new(); - for c in code.chars() { + let chars: Vec = code.chars().collect(); + + for (i, &c) in chars.iter().enumerate() { + let prev = if i > 0 { Some(chars[i - 1]) } else { None }; + let next = if i < chars.len() - 1 { + Some(chars[i + 1]) + } else { + None + }; + if c == ' ' { - ret += " / "; - } else if let Some(morse) = morse_map.get(&c) { - ret += morse; + if let (Some(p), Some(n)) = (prev, next) { + if char_to_morse.contains_key(&p) && char_to_morse.contains_key(&n) { + ret += "/ "; + } + } + } else if let Some(encoded) = char_to_morse.get(&c) { + ret += encoded; + ret += " "; } - ret += " "; } - ret + ret.trim_end().to_string() } pub fn write_morse(filename: &str, morse: &str) { @@ -101,3 +114,90 @@ pub fn write_morse(filename: &str, morse: &str) { } write_freq(&mut writer, 0.0, UNIT_TIME); // End padding } + +pub fn from_morse(morse: &str) -> String { + let morse_to_char: HashMap<&str, char> = HashMap::from([ + (".-", 'a'), + ("-...", 'b'), + ("-.-.", 'c'), + ("-..", 'd'), + (".", 'e'), + ("..-.", 'f'), + ("--.", 'g'), + ("....", 'h'), + ("..", 'i'), + (".---", 'j'), + ("-.-", 'k'), + (".-..", 'l'), + ("--", 'm'), + ("-.", 'n'), + ("---", 'o'), + (".--.", 'p'), + ("--.-", 'q'), + (".-.", 'r'), + ("...", 's'), + ("-", 't'), + ("..-", 'u'), + ("...-", 'v'), + (".--", 'w'), + ("-..-", 'x'), + ("-.--", 'y'), + ("--..", 'z'), + (".----", '1'), + ("..---", '2'), + ("...--", '3'), + ("....-", '4'), + (".....", '5'), + ("-....", '6'), + ("--...", '7'), + ("---..", '8'), + ("----.", '9'), + ("-----", '0'), + ("/", ' '), + ]); + + let mut look = String::new(); + let mut ret = String::new(); + + for c in morse.chars() { + if c == ' ' { + if let Some(decoded) = morse_to_char.get(&look[..]) { + ret.push(*decoded); + look = "".to_string(); + } + } else { + look.push(c); + } + } + + if !look.is_empty() { + if let Some(decoded) = morse_to_char.get(&look[..]) { + ret.push(*decoded); + } + } + + ret +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_to_morse() { + let encoded = to_morse("This iS a Message 01 written in morse!"); + assert_eq!(encoded, "- .... .. ... / .. ... / .- / -- . ... ... .- --. . / ----- .---- / .-- .-. .. - - . -. / .. -. / -- --- .-. ... .") + } + + #[test] + fn test_weird_input_to_morse() { + let encoded = to_morse("!@(@*$)(!*@)($*)!@ hey this is good char now )!(@*)][][]][]"); + assert_eq!(encoded, ".... . -.-- / - .... .. ... / .. ... / --. --- --- -.. / -.-. .... .- .-. / -. --- .--") + } + + #[test] + fn test_from_morse() { + let decoded = from_morse("-.. .- -. .. ... .... / --. .... .- .. ... .- -. / .--. ..- - . .-. .- / .- .... -- .- -.. .."); + assert_eq!(decoded, "danish ghaisan putera ahmadi"); + } +}