1pub fn to_pascal_case(s: &str) -> String {
14 fn is_separator(c: char) -> bool {
15 matches!(c, '_' | '-' | '.')
16 }
17
18 let has_separator = s.chars().any(is_separator);
19 let has_lowercase = s.chars().any(|c| c.is_ascii_lowercase());
20 let starts_uppercase = s.chars().next().is_some_and(|c| c.is_ascii_uppercase());
21
22 if starts_uppercase && has_lowercase && !has_separator {
24 return s.to_string();
25 }
26
27 let mut result = String::with_capacity(s.len());
28 let mut capitalize_next = true;
29 for c in s.chars() {
30 if is_separator(c) {
31 capitalize_next = true;
32 continue;
33 }
34 if capitalize_next {
35 result.push(c.to_ascii_uppercase());
36 capitalize_next = false;
37 } else {
38 result.push(c.to_ascii_lowercase());
39 }
40 }
41 result
42}
43
44pub fn to_snake_case(s: &str) -> String {
53 let mut result = String::new();
54 for (i, c) in s.chars().enumerate() {
55 if c.is_ascii_uppercase() {
56 if i > 0 && !result.ends_with('_') {
57 result.push('_');
58 }
59 result.push(c.to_ascii_lowercase());
60 } else {
61 result.push(c);
62 }
63 }
64 result
65}