ferric_crypto_lib 0.2.7

A library for Ferric Crypto
Documentation
use crate::crypto_systems::mono_alphabet::{MonoError, Monosubstitution};
use crate::Traits::Decrypt;

impl Decrypt<MonoError, String, String> for Monosubstitution {
    /// Decrypts a string using the Monosubstitution cipher.
    ///
    /// This function replaces each character in the input string with its corresponding character in the dictionary.
    /// Non-alphabetic characters are left unchanged.
    ///
    /// # Arguments
    ///
    /// * `input` - A `String` that holds the text to be decrypted.
    ///
    /// # Returns
    ///
    /// * A `Result<String, MonoError>` which is `Ok` if the decryption is successful, and `Err` otherwise.
    ///   The `Ok` variant contains the decrypted text, and the `Err` variant contains an error type.
    ///
    /// # Example
    ///
    /// ```
    /// # use ferric_crypto_lib::crypto_systems::mono_alphabet::{MonoError, Monosubstitution};
    /// # use ferric_crypto_lib::Traits::Decrypt;
    /// # use std::collections::HashMap;
    ///
    /// let dict: HashMap<char, char> = [('d', 'a'), ('e', 'b'), ('f', 'c')].iter().cloned().collect();
    /// let mono = Monosubstitution::from(dict);
    /// let result = mono.decrypt("def".to_string()).unwrap();
    /// assert_eq!(result, "abc");
    /// ```
    fn decrypt(&self, input: String) -> Result<String, MonoError> {
        let mut decrypted = String::new();

        for c in input.to_lowercase().chars() {

            if self.dict.keys().any(|&k| k == c) {
                // Find the corresponding key for the value in the dictionary
                for (key, value) in &self.dict {
                    if *key == c {
                        decrypted.push(*value);
                    }
                }
            } else {
                return Err(MonoError::InvalidCharacter(c));
            }
        }

        Ok(decrypted)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::Traits::Decrypt;
    //use crate::crypto_systems::mono_alphabet::MonoError;
    use std::collections::HashMap;

    #[test]
    fn decrypts_lowercase_letters() {
        let dict: HashMap<char, char> = [('d', 'a'), ('e', 'b'), ('f', 'c')]
            .iter()
            .cloned()
            .collect();
        #[cfg(feature = "debug")]
        {
            // print all keys
            for (key, value) in &dict {
                dbg!(&key);
                dbg!(&value);
            }
        }
        let mono = Monosubstitution::from(dict);
        let result = mono.decrypt("def".to_string()).unwrap();
        assert_eq!(result, "abc");
    }

    #[test]
    fn decrypts_uppercase_letters() {
        let dict: HashMap<char, char> = [('d', 'a'), ('e', 'b'), ('f', 'c')]
            .iter()
            .cloned()
            .collect();
        let mono = Monosubstitution::from(dict);
        let result = mono.decrypt("DEF".to_string()).unwrap();
        assert_eq!(result, "abc");
    }

    #[test]
    fn decrypts_mixed_case() {
        let dict: HashMap<char, char> = [('d', 'a'), ('e', 'b'), ('f', 'c')]
            .iter()
            .cloned()
            .collect();
        let mono = Monosubstitution::from(dict);
        let result = mono.decrypt("DeF".to_string()).unwrap();
        assert_eq!(result, "abc");
    }

    #[test]
    fn decrypts_empty_string() {
        let mono = Monosubstitution::new();
        let result = mono.decrypt("".to_string()).unwrap();
        assert_eq!(result, "");
    }

    #[test]
    fn decrypts_non_alphabetic_characters() {
        let mono = Monosubstitution::new();
        let result = mono.decrypt("123!@#".to_string()).unwrap_err();
        assert_eq!(result, MonoError::InvalidCharacter('1'));
    }
}