wafrift_encoding/encoding/keyword/
case.rs1pub fn alternating_case(payload: &str, start_upper: bool) -> String {
7 let mut upper = start_upper;
8 payload
9 .chars()
10 .map(|ch| {
11 if ch.is_ascii_alphabetic() {
12 let result = if upper {
13 ch.to_ascii_uppercase()
14 } else {
15 ch.to_ascii_lowercase()
16 };
17 upper = !upper;
18 result
19 } else {
20 ch
21 }
22 })
23 .collect()
24}
25
26pub fn case_alternate(payload: &str) -> String {
32 alternating_case(payload, true)
33}
34
35pub fn random_case_alternate(payload: &str) -> String {
40 payload
41 .chars()
42 .map(|ch| {
43 if ch.is_ascii_alphabetic() {
44 if rand::random::<bool>() {
45 ch.to_ascii_uppercase()
46 } else {
47 ch.to_ascii_lowercase()
48 }
49 } else {
50 ch
51 }
52 })
53 .collect()
54}
55
56pub fn lowercase(payload: &str) -> String {
58 payload.to_ascii_lowercase()
59}
60
61pub fn uppercase(payload: &str) -> String {
63 payload.to_ascii_uppercase()
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn case_alternate_basic() {
72 assert_eq!(case_alternate("select"), "SeLeCt");
73 }
74
75 #[test]
76 fn random_case_non_deterministic() {
77 let a = random_case_alternate("SELECT");
78 let b = random_case_alternate("SELECT");
79 assert_eq!(a.to_ascii_lowercase(), "select");
81 assert_eq!(b.to_ascii_lowercase(), "select");
82 }
83
84 #[test]
85 fn lowercase_basic() {
86 assert_eq!(lowercase("SeLeCt"), "select");
87 }
88
89 #[test]
90 fn uppercase_basic() {
91 assert_eq!(uppercase("SeLeCt"), "SELECT");
92 }
93
94 #[test]
95 fn case_alternate_idempotent_after_first() {
96 let once = case_alternate("select");
97 let twice = case_alternate(&once);
98 assert_eq!(
99 once, twice,
100 "case_alternate must be idempotent after first application"
101 );
102 assert_eq!(once, "SeLeCt");
103 }
104
105 #[test]
106 fn random_case_not_idempotent() {
107 let a = random_case_alternate("SELECT");
108 let b = random_case_alternate(&a);
109 assert_ne!(
111 a, b,
112 "random_case should re-randomise on second application"
113 );
114 }
115}