1#[allow(deprecated, unused_imports)]
6use std::ascii::AsciiExt;
7
8use std::str::FromStr;
9
10use self::RenameRule::*;
11
12#[derive(Copy, Clone, PartialEq)]
14pub enum RenameRule {
15 None,
17 LowerCase,
19 UPPERCASE,
21 PascalCase,
24 CamelCase,
26 SnakeCase,
29 ScreamingSnakeCase,
32 KebabCase,
34 ScreamingKebabCase,
36}
37
38impl RenameRule {
39 pub fn apply_to_variant(&self, variant: &str) -> String {
41 match *self {
42 None | PascalCase => variant.to_owned(),
43 LowerCase => variant.to_ascii_lowercase(),
44 UPPERCASE => variant.to_ascii_uppercase(),
45 CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
46 SnakeCase => {
47 let mut snake = String::new();
48 for (i, ch) in variant.char_indices() {
49 if i > 0 && ch.is_uppercase() {
50 snake.push('_');
51 }
52 snake.push(ch.to_ascii_lowercase());
53 }
54 snake
55 }
56 ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
57 KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
58 ScreamingKebabCase => ScreamingSnakeCase
59 .apply_to_variant(variant)
60 .replace('_', "-"),
61 }
62 }
63
64 pub fn apply_to_field(&self, field: &str) -> String {
66 match *self {
67 None | LowerCase | SnakeCase => field.to_owned(),
68 UPPERCASE => field.to_ascii_uppercase(),
69 PascalCase => {
70 let mut pascal = String::new();
71 let mut capitalize = true;
72 for ch in field.chars() {
73 if ch == '_' {
74 capitalize = true;
75 } else if capitalize {
76 pascal.push(ch.to_ascii_uppercase());
77 capitalize = false;
78 } else {
79 pascal.push(ch);
80 }
81 }
82 pascal
83 }
84 CamelCase => {
85 let pascal = PascalCase.apply_to_field(field);
86 pascal[..1].to_ascii_lowercase() + &pascal[1..]
87 }
88 ScreamingSnakeCase => field.to_ascii_uppercase(),
89 KebabCase => field.replace('_', "-"),
90 ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"),
91 }
92 }
93}
94
95impl FromStr for RenameRule {
96 type Err = ();
97
98 fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
99 match rename_all_str {
100 "lowercase" => Ok(LowerCase),
101 "UPPERCASE" => Ok(UPPERCASE),
102 "PascalCase" => Ok(PascalCase),
103 "camelCase" => Ok(CamelCase),
104 "snake_case" => Ok(SnakeCase),
105 "SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase),
106 "kebab-case" => Ok(KebabCase),
107 "SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase),
108 _ => Err(()),
109 }
110 }
111}
112
113#[test]
114fn rename_variants() {
115 for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[
116 (
117 "Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
118 ),
119 (
120 "VeryTasty",
121 "verytasty",
122 "VERYTASTY",
123 "veryTasty",
124 "very_tasty",
125 "VERY_TASTY",
126 "very-tasty",
127 "VERY-TASTY",
128 ),
129 ("A", "a", "A", "a", "a", "A", "a", "A"),
130 ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
131 ] {
132 assert_eq!(None.apply_to_variant(original), original);
133 assert_eq!(LowerCase.apply_to_variant(original), lower);
134 assert_eq!(UPPERCASE.apply_to_variant(original), upper);
135 assert_eq!(PascalCase.apply_to_variant(original), original);
136 assert_eq!(CamelCase.apply_to_variant(original), camel);
137 assert_eq!(SnakeCase.apply_to_variant(original), snake);
138 assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
139 assert_eq!(KebabCase.apply_to_variant(original), kebab);
140 assert_eq!(
141 ScreamingKebabCase.apply_to_variant(original),
142 screaming_kebab
143 );
144 }
145}
146
147#[test]
148fn rename_fields() {
149 for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[
150 (
151 "outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
152 ),
153 (
154 "very_tasty",
155 "VERY_TASTY",
156 "VeryTasty",
157 "veryTasty",
158 "VERY_TASTY",
159 "very-tasty",
160 "VERY-TASTY",
161 ),
162 ("a", "A", "A", "a", "A", "a", "A"),
163 ("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
164 ] {
165 assert_eq!(None.apply_to_field(original), original);
166 assert_eq!(UPPERCASE.apply_to_field(original), upper);
167 assert_eq!(PascalCase.apply_to_field(original), pascal);
168 assert_eq!(CamelCase.apply_to_field(original), camel);
169 assert_eq!(SnakeCase.apply_to_field(original), original);
170 assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
171 assert_eq!(KebabCase.apply_to_field(original), kebab);
172 assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
173 }
174}