pub use super::traits::CipherPuzzle;
use super::util::shift_char;
pub struct Caesar {
shift: u8,
}
impl Caesar {
pub fn new(shift: u8) -> Self {
Self { shift: shift % 26 }
}
}
impl CipherPuzzle for Caesar {
fn encrypt(&self, plaintext: &str) -> String {
plaintext
.chars()
.map(|c| shift_char(c, self.shift))
.collect()
}
fn decrypt(&self, ciphertext: &str) -> String {
ciphertext
.chars()
.map(|c| shift_char(c, 26 - self.shift))
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn caesar_encrypts_correctly() {
let c = Caesar { shift: 3 };
let plain = "Hello, World!";
let expected = "Khoor, Zruog!";
let encrypted = c.encrypt(plain);
assert_eq!(encrypted, expected);
}
#[test]
fn caesar_upper_with_wrap_encrypts_correctly() {
let c = Caesar { shift: 3 };
let plain = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let expected = "DEFGHIJKLMNOPQRSTUVWXYZABC";
let encrypted = c.encrypt(plain);
assert_eq!(encrypted, expected);
}
#[test]
fn caesar_lower_with_wrap_encrypts_correctly() {
let c = Caesar { shift: 3 };
let plain = "abcdefghijklmnopqrstuvwxyz";
let expected = "defghijklmnopqrstuvwxyzabc";
let encrypted = c.encrypt(plain);
assert_eq!(encrypted, expected);
}
#[test]
fn caesar_encrypt_decrypt() {
let c = Caesar { shift: 3 };
let plain = "Hello, World!";
let encrypted = c.encrypt(plain);
let decrypted = c.decrypt(&encrypted);
assert_eq!(decrypted, plain);
}
}