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
/// Convert input to camel case
pub fn camel_case(name: &str) -> String {
    let mut new_word = true;
    name.chars().fold("".to_string(), |mut result, ch| {
        if ch == '-' || ch == '_' || ch == ' ' {
            new_word = true;
            result
        } else {
            result.push(if new_word { ch.to_ascii_uppercase() } else { ch });
            new_word = false;
            result
        }
    })
}

/// Convert input to snake case
/// For the purpose of the AMQP codegen usage, we also handle a few special cases:
/// "type" becomes "type_"
/// "return" becomes "return_"
/// A word needs to be composed of at least two letters, this makes UInt become uint and not u_int
pub fn snake_case(name: &str) -> String {
    match name {
        "type"   => "type_".to_string(),
        "return" => "return_".to_string(),
        name     => {
            let mut new_word       = false;
            let mut last_was_upper = false;
            name.chars().fold("".to_string(), |mut result, ch| {
                if ch == '-' || ch == '_' || ch == ' ' {
                    new_word = true;
                    result
                } else {
                    let uppercase = ch.is_uppercase();
                    if new_word || (!last_was_upper && !result.is_empty() && uppercase) {
                        result.push('_');
                        new_word = false;
                    }
                    last_was_upper = uppercase;
                    result.push(if uppercase { ch.to_ascii_lowercase() } else { ch });
                    result
                }
            })
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_camel_case() {
        assert_eq!(camel_case(""),                  "");
        assert_eq!(camel_case("foobar"),            "Foobar");
        assert_eq!(camel_case("FooBar"),            "FooBar");
        assert_eq!(camel_case("foo_bar"),           "FooBar");
        assert_eq!(camel_case("_foo__bar baz-zzz"), "FooBarBazZzz");
    }

    #[test]
    fn test_snake_case() {
        assert_eq!(snake_case(""),               "");
        assert_eq!(snake_case("Foobar"),         "foobar");
        assert_eq!(snake_case("FooBar"),         "foo_bar");
        assert_eq!(snake_case("Foo-BarBaz_zzz"), "foo_bar_baz_zzz");
    }

    #[test]
    fn test_snake_case_uint() {
        /* special case: we want UInt to be converted as uint */
        assert_eq!(snake_case("UInt"),     "uint");
        assert_eq!(snake_case("LongUInt"), "long_uint");
    }
}