1
2enum CamelCaseState {
3 Start,
4 Lower,
5 Upper,
6 UpperUpper,
7 Digit,
8}
9
10pub fn camel_case_to_title_case(camel_case: &str) -> String {
11 use CamelCaseState::*;
12
13 let mut answer = String::with_capacity(camel_case.len());
14 let mut state = Start;
15
16 for c in camel_case.chars() {
17 if c.is_ascii_digit() {
18 match state {
19 Start | Digit => {
20 answer.push(c);
21 state = Digit;
22 }
23 Lower | Upper | UpperUpper => {
24 answer.push(' ');
25 answer.push(c);
26 state = Digit;
27 }
28 }
29 } else if c.is_ascii_uppercase() {
30 match state {
31 Start => {
32 answer.push(c);
33 state = Upper;
34 }
35 Upper | UpperUpper => {
36 answer.push(c);
37 state = UpperUpper;
38 }
39 Lower | Digit => {
40 answer.push(' ');
41 answer.push(c);
42 state = Upper;
43 }
44 }
45 } else {
46 match state {
47 Start => {
48 answer.push(c.to_ascii_uppercase());
49 state = Lower;
50 }
51 Lower | Upper => {
52 answer.push(c);
53 state = Lower;
54 }
55 UpperUpper => {
56 if let Some(capital) = answer.pop() {
57 answer.push(' ');
58 answer.push(capital);
59 }
60 answer.push(c);
61 state = Lower;
62 }
63 Digit => {
64 answer.push(' ');
65 answer.push(c.to_ascii_uppercase());
66 state = Upper;
67 }
68 }
69 }
70 }
71
72 answer
73}