prost_reflect/dynamic/serde/
case.rs
1pub(crate) fn snake_case_to_camel_case(dst: &mut String, src: &str) -> Result<(), ()> {
4 let mut ucase_next = false;
5 for ch in src.chars() {
6 if ch.is_ascii_uppercase() {
7 return Err(());
8 }
9
10 if ucase_next {
11 let upper_ch = ch.to_ascii_uppercase();
12 if upper_ch == ch {
13 return Err(());
14 }
15
16 dst.push(upper_ch);
17 ucase_next = false;
18 } else if ch == '_' {
19 ucase_next = true;
20 } else {
21 dst.push(ch)
22 }
23 }
24
25 Ok(())
26}
27
28pub(crate) fn camel_case_to_snake_case(result: &mut String, part: &str) -> Result<(), ()> {
29 for ch in part.chars() {
30 if ch.is_ascii_uppercase() {
31 result.push('_');
32 result.push(ch.to_ascii_lowercase());
33 } else if ch == '_' {
34 return Err(());
35 } else {
36 result.push(ch);
37 }
38 }
39
40 Ok(())
41}
42
43#[cfg(test)]
44mod tests {
45 use proptest::prelude::*;
46
47 use super::*;
48
49 #[test]
50 fn snake_to_camel() {
51 let mut buf = String::new();
52
53 snake_case_to_camel_case(&mut buf, "foo").unwrap();
54 assert_eq!(&buf, "foo");
55 buf.clear();
56
57 snake_case_to_camel_case(&mut buf, "foo_bar").unwrap();
58 assert_eq!(&buf, "fooBar");
59 buf.clear();
60 }
61
62 #[test]
63 fn camel_to_snake() {
64 let mut buf = String::new();
65
66 camel_case_to_snake_case(&mut buf, "foo").unwrap();
67 assert_eq!(&buf, "foo");
68 buf.clear();
69
70 camel_case_to_snake_case(&mut buf, "fooBar").unwrap();
71 assert_eq!(&buf, "foo_bar");
72 buf.clear();
73 }
74
75 #[test]
76 fn bad_roundtrips() {
77 let mut buf = String::new();
78 assert!(snake_case_to_camel_case(&mut buf, "fooBar").is_err());
79 assert!(snake_case_to_camel_case(&mut buf, "foo_3_bar").is_err());
80 assert!(snake_case_to_camel_case(&mut buf, "foo__bar").is_err());
81 }
82
83 proptest! {
84 #[test]
85 fn roundtrip_cases(snake_case in "[a-zA-Z0-9]+") {
86 let mut camel_case = String::new();
87 if snake_case_to_camel_case(&mut camel_case, &snake_case).is_ok() {
88 let mut roundtripped_snake_case = String::new();
89 camel_case_to_snake_case(&mut roundtripped_snake_case, &camel_case).unwrap();
90
91 prop_assert_eq!(snake_case, roundtripped_snake_case);
92 }
93 }
94 }
95}