diff --git a/src/ciphers/mod.rs b/src/ciphers/mod.rs index 76b13ea..c97cade 100644 --- a/src/ciphers/mod.rs +++ b/src/ciphers/mod.rs @@ -13,7 +13,7 @@ mod xor; pub use self::aes::{aes_decrypt, aes_encrypt, AesKey}; pub use self::another_rot13::another_rot13; pub use self::caesar::caesar; -pub use self::morse_code::encode; +pub use self::morse_code::{encode, decode}; pub use self::polybius::{decode_ascii, encode_ascii}; pub use self::rot13::rot13; pub use self::sha256::sha256; diff --git a/src/ciphers/morse_code.rs b/src/ciphers/morse_code.rs index 2d4d2fa..dce9c4f 100644 --- a/src/ciphers/morse_code.rs +++ b/src/ciphers/morse_code.rs @@ -1,8 +1,35 @@ use std::collections::HashMap; +// The character used to represent an unknown morse code sequence const UNKNOWN_CHARACTER: &str = "........"; + +// The character used to represent an unknown morse code character const _UNKNOWN_MORSE_CHARACTER: &str = "_"; +/// Encode a message into morse code. +/// +/// Given a message, this function encodes it into morse code. +/// It uses a dictionary to map each character to its corresponding morse code sequence. +/// If a character is not found in the dictionary, it is replaced with the unknown character sequence. +/// +/// # Arguments +/// +/// * `message` - The message to encode into morse code. +/// +/// # Returns +/// +/// The encoded morse code as a string. +/// +/// # Examples +/// +/// ```rust +/// use rust_algorithms::ciphers::encode; +/// +/// let message = "Hello Morse"; +/// let cipher = encode(message); +/// +/// assert_eq!(cipher, ".... . .-.. .-.. --- / -- --- .-. ... ."); +/// ``` pub fn encode(message: &str) -> String { let dictionary = _morse_dictionary(); message @@ -22,6 +49,13 @@ macro_rules! map { }; } +/// Create the morse code to alphanumeric dictionary. +/// +/// This function creates a HashMap that maps each morse code sequence to its corresponding alphanumeric character. +/// +/// # Returns +/// +/// The morse code to alphanumeric dictionary as a HashMap. fn _morse_dictionary() -> HashMap<&'static str, &'static str> { map! { "A" => ".-", "B" => "-...", "C" => "-.-.", @@ -48,6 +82,13 @@ fn _morse_dictionary() -> HashMap<&'static str, &'static str> { } } +/// Create the morse code to alphanumeric dictionary. +/// +/// This function creates a HashMap that maps each morse code sequence to its corresponding alphanumeric character. +/// +/// # Returns +/// +/// The morse code to alphanumeric dictionary as a HashMap. fn _morse_to_alphanumeric_dictionary() -> HashMap<&'static str, &'static str> { map! { ".-" => "A", "-..." => "B", "-.-." => "C", @@ -74,6 +115,17 @@ fn _morse_to_alphanumeric_dictionary() -> HashMap<&'static str, &'static str> { } } +/// Check if a string is a valid morse code part. +/// +/// This function checks if a string contains only valid morse code characters ('.', '-', and ' '). +/// +/// # Arguments +/// +/// * `string` - The string to check. +/// +/// # Returns +/// +/// `true` if the string is a valid morse code part, `false` otherwise. fn _check_part(string: &str) -> bool { for c in string.chars() { match c { @@ -84,30 +136,45 @@ fn _check_part(string: &str) -> bool { true } +/// Check if a string is a valid morse code. +/// +/// This function checks if a string is a valid morse code by splitting it into parts and checking each part. +/// +/// # Arguments +/// +/// * `string` - The string to check. +/// +/// # Returns +/// +/// `true` if the string is a valid morse code, `false` otherwise. fn _check_all_parts(string: &str) -> bool { string.split('/').all(_check_part) } -fn _decode_token(string: &str) -> String { - _morse_to_alphanumeric_dictionary() - .get(string) - .unwrap_or(&_UNKNOWN_MORSE_CHARACTER) - .to_string() -} - -fn _decode_part(string: &str) -> String { - string - .split(' ') - .map(_decode_token) - .collect::>() - .join("") -} - -/// Convert morse code to ascii. +/// Decode a morse code into an alphanumeric message. /// -/// Given a morse code, return the corresponding message. -/// If the code is invalid, the undecipherable part of the code is replaced by `_`. -#[cfg(test)] +/// Given a morse code, this function decodes it into an alphanumeric message. +/// It uses a dictionary to map each morse code sequence to its corresponding alphanumeric character. +/// If a morse code sequence is not found in the dictionary, it is replaced with the unknown morse code character. +/// If the morse code is invalid, an `InvalidData` error is returned. +/// +/// # Arguments +/// +/// * `string` - The morse code to decode into an alphanumeric message. +/// +/// # Returns +/// +/// The decoded alphanumeric message as a `Result` containing a `String` if successful, or an `InvalidData` error. +/// +/// # Examples +/// +/// ```rust +/// use rust_algorithms::ciphers::decode; +/// +/// let message = decode(".... . .-.. .-.. --- / -- --- .-. ... .").unwrap(); +/// +/// assert_eq!(message, "HELLO MORSE"); +/// ``` pub fn decode(string: &str) -> Result { if !_check_all_parts(string) { return Err(std::io::Error::new( @@ -125,6 +192,47 @@ pub fn decode(string: &str) -> Result { Ok(partitions.join(" ")) } +/// Decode a morse code token into an alphanumeric character. +/// +/// This function decodes a morse code token into its corresponding alphanumeric character. +/// It uses a dictionary to map each morse code sequence to its corresponding alphanumeric character. +/// If the morse code token is not found in the dictionary, it is replaced with the unknown morse code character. +/// +/// # Arguments +/// +/// * `string` - The morse code token to decode into an alphanumeric character. +/// +/// # Returns +/// +/// The decoded alphanumeric character as a string. +/// +fn _decode_token(string: &str) -> String { + _morse_to_alphanumeric_dictionary() + .get(string) + .unwrap_or(&_UNKNOWN_MORSE_CHARACTER) + .to_string() +} + +/// Decode a morse code part into an alphanumeric string. +/// +/// This function decodes a morse code part into its corresponding alphanumeric string. +/// It splits the part into tokens, decodes each token, and joins them together. +/// +/// # Arguments +/// +/// * `string` - The morse code part to decode into an alphanumeric string. +/// +/// # Returns +/// +/// The decoded alphanumeric string. +fn _decode_part(string: &str) -> String { + string + .split(' ') + .map(_decode_token) + .collect::>() + .join("") +} + #[cfg(test)] mod tests { use super::*;