1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
mod keygen;
pub use keygen::KeyGenerator;
const UPPERCASE_OFFSET: u32 = 65;
const LOWERCASE_OFFSET: u32 = 97;
const ALPHABET_SIZE: u32 = 26;
fn normalize_char_codepoint(start: char) -> Option<(u32, u32)> {
let start_code_point = start as u32;
let offset_to_use: u32 = if (65..91).contains(&start_code_point) {
UPPERCASE_OFFSET
} else if (97..123).contains(&start_code_point) {
LOWERCASE_OFFSET
} else {
0u32
};
if offset_to_use != 0u32 {
let normalized_char_point = (start_code_point - offset_to_use) % ALPHABET_SIZE;
println!("normalized_char_point = {:?}", normalized_char_point);
Some((normalized_char_point, offset_to_use))
} else {
None
}
}
pub fn wrapped_shift_letters(to_shift: char, key_char: char) -> char {
let normalized_start = normalize_char_codepoint(to_shift);
println!("normalized_start = {:?}", normalized_start);
let normalized_shift = normalize_char_codepoint(key_char);
println!("normalized_shift = {:?}", normalized_shift);
if normalized_start == None || normalized_shift == None {
println!(
"Either normalized_start ({:?}) or normalized_shift ({:?}) is `None`",
normalized_start, normalized_shift
);
return to_shift;
}
let (start, offset) = normalized_start.unwrap();
let (shift, _) = normalized_shift.unwrap();
let transformed: u32 = start + shift + offset;
std::char::from_u32(transformed).unwrap_or(to_shift)
}
#[cfg(test)]
mod tests {
use super::keygen::KeyGenerator;
use super::wrapped_shift_letters;
#[test]
fn shifts_correct_amount() {
let mut keygen = KeyGenerator::new(String::from("queen"), false);
let key = keygen.next().unwrap();
println!("key to shift by: {:?}", key);
let shifted = wrapped_shift_letters('a', key);
assert_eq!(shifted, 'q');
}
}