fancy_mocker/lib.rs
1mod tests;
2
3fn start_uppercase(text: &str) -> bool {
4 let ambiguous_char: &[_] = &['i', 'I', 'l', 'L'];
5
6 match text.find(ambiguous_char) {
7 Some(index) => {
8 match text.chars().nth(index).unwrap() {
9 'i' | 'I' => index % 2 != 0,
10 _ => index % 2 == 0
11 }
12 },
13 None => false
14 }
15}
16
17fn should_be_uppercase(c: char) -> Option<bool> {
18 match c {
19 'i' | 'I' => Some(false),
20 'l' | 'L' => Some(true),
21 _ => None
22 }
23}
24
25/// Returns a String with the letters changed to alternate
26/// between uppercase and lowercase.
27///
28/// All instances of the letters L and i are set to uppercase
29/// and lowercase, respectively.
30/// The case of the first letter in the input is determined based on
31/// where either aforementioned letter first appears,
32/// defaulting to lowercase if neither appears in the text.
33///
34/// The capitalisation in the input is not preserved, although
35/// all non-ascii and non-alphabetic characters are preserved as-is.
36///
37/// # Examples
38///
39/// ```
40/// let hello = "Hello, world!";
41/// let ironic_hello = fancy_mocker::mock(hello);
42///
43/// assert_eq!(ironic_hello, "HeLLo, WoRLd!");
44/// ```
45pub fn mock(text: &str) -> String {
46
47
48 let mut uppercase = start_uppercase(text);
49
50 let mut result = String::with_capacity(text.len());
51
52 for c in text.chars() {
53 if !c.is_ascii_alphabetic() {
54 result.push(c);
55 } else if should_be_uppercase(c).unwrap_or(uppercase) {
56 result.push(c.to_ascii_uppercase());
57 uppercase = false;
58 } else {
59 result.push(c.to_ascii_lowercase());
60 uppercase = true;
61 }
62 }
63
64 result
65}