use super::alphabet;
use super::alphabet::Alphabet;
pub fn shift_substitution<F>(text: &str, calc_index: F) -> Result<String, &'static str>
where
F: Fn(usize) -> usize,
{
let mut s_text = String::new();
for c in text.chars() {
let pos = alphabet::STANDARD.find_position(c);
match pos {
Some(pos) => {
let si = calc_index(pos);
if let Some(s) = alphabet::STANDARD.get_letter(si, c.is_uppercase()) {
s_text.push(s);
} else {
return Err("Calculated an index outside of the known alphabet.");
}
}
None => s_text.push(c), }
}
Ok(s_text)
}
pub fn key_substitution<F>(
text: &str,
keystream: &mut Vec<char>,
calc_index: F,
) -> Result<String, &'static str>
where
F: Fn(usize, usize) -> usize,
{
let mut s_text = String::new();
for tc in text.chars() {
let tpos = alphabet::STANDARD.find_position(tc);
match tpos {
Some(ti) => {
if keystream.len() < 1 {
return Err("Keystream is not large enough for full substitution of message");
}
let kc = keystream[0];
if let Some(ki) = alphabet::STANDARD.find_position(kc) {
let si = calc_index(ti, ki);
if let Some(s) = alphabet::STANDARD.get_letter(si, tc.is_uppercase()) {
s_text.push(s);
} else {
return Err(
"Calculated a substitution index outside of the known alphabet.",
);
}
keystream.remove(0);
} else {
return Err("Keystream contains a non-alphabetic symbol.");
}
}
None => s_text.push(tc), }
}
Ok(s_text)
}