use crate::cryptable::Crypt;
#[derive(Debug)]
pub(crate) struct SquarePosition {
pub row: u8,
pub column: u8,
}
pub(crate) struct CryptResult {
pub a: char,
pub b: char,
}
pub(crate) struct Payload {
pub payload: String,
pub counter: usize,
}
#[derive(PartialEq)]
pub(crate) enum CryptModus {
Encrypt,
Decrypt,
}
impl Payload {
pub(crate) fn new(payload: String) -> Self {
Payload {
payload,
counter: 0,
}
}
pub(crate) fn crypt_payload(
&mut self,
cipher: &impl Crypt,
modus: &crate::structs::CryptModus,
) -> Result<String, crate::errors::CharNotInKeyError> {
let mut payload_encrypted = String::new();
loop {
let digram = self.next();
let [a, b] = match digram {
Some(d) => d,
None => break,
};
match cipher.crypt(a, b, modus) {
Ok(digram_crypt) => {
payload_encrypted += &String::from(digram_crypt.a);
payload_encrypted += &String::from(digram_crypt.b);
}
Err(e) => return Err(e),
};
}
Ok(payload_encrypted)
}
}
impl Iterator for Payload {
type Item = [char; 2];
fn next(&mut self) -> Option<Self::Item> {
if self.counter < self.payload.len() {
let first_member = &self.payload[self.counter..self.counter + 1];
let second_member = match self.counter + 2 <= self.payload.len() {
true => &self.payload[self.counter + 1..self.counter + 2],
false => "X",
};
if first_member == second_member {
let char_list: Vec<char> = first_member.chars().collect();
self.counter += 1;
Some([char_list[0], 'X'])
} else {
let char_list_first: Vec<char> = first_member.chars().collect();
let char_list_second: Vec<char> = second_member.chars().collect();
self.counter += 2;
Some([char_list_first[0], char_list_second[0]])
}
} else {
None
}
}
}