Skip to content

Commit

Permalink
added docs to morse_code. Modified mod.rs in ciphers to include decod…
Browse files Browse the repository at this point in the history
…e as well as encode. We may need to rename these functions to make it clear way they are doing, or change the way the morse_code module is being included to make it clearer what the function names mean.
  • Loading branch information
scriptandcompile committed Jun 9, 2024
1 parent 817f850 commit 5a53f0b
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/ciphers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
146 changes: 127 additions & 19 deletions src/ciphers/morse_code.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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" => "-.-.",
Expand All @@ -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",
Expand All @@ -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 {
Expand All @@ -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::<Vec<String>>()
.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<String, std::io::Error> {
if !_check_all_parts(string) {
return Err(std::io::Error::new(
Expand All @@ -125,6 +192,47 @@ pub fn decode(string: &str) -> Result<String, std::io::Error> {
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::<Vec<String>>()
.join("")
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 5a53f0b

Please sign in to comment.