Skip to content

Commit d509b3b

Browse files
committed
Replaced case conversion with heck
1 parent bc8ad8a commit d509b3b

File tree

4 files changed

+60
-111
lines changed

4 files changed

+60
-111
lines changed

postgres-derive/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ test = false
1515
syn = "2.0"
1616
proc-macro2 = "1.0"
1717
quote = "1.0"
18+
heck = "0.4"

postgres-derive/src/case.rs

Lines changed: 45 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#[allow(deprecated, unused_imports)]
22
use std::ascii::AsciiExt;
33

4+
use heck::{
5+
ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase, ToTrainCase,
6+
ToUpperCamelCase,
7+
};
8+
49
use self::RenameRule::*;
510

611
/// The different possible ways to change case of fields in a struct, or variants in an enum.
@@ -26,78 +31,56 @@ pub enum RenameRule {
2631
KebabCase,
2732
/// Rename direct children to "SCREAMING-KEBAB-CASE" style.
2833
ScreamingKebabCase,
34+
35+
/// Rename direct children to "Train-Case" style.
36+
TrainCase,
2937
}
3038

31-
pub static RENAME_RULES: &[(&str, RenameRule)] = &[
32-
("lowercase", LowerCase),
33-
("UPPERCASE", UpperCase),
34-
("PascalCase", PascalCase),
35-
("camelCase", CamelCase),
36-
("snake_case", SnakeCase),
37-
("SCREAMING_SNAKE_CASE", ScreamingSnakeCase),
38-
("kebab-case", KebabCase),
39-
("SCREAMING-KEBAB-CASE", ScreamingKebabCase),
39+
pub const RENAME_RULES: &[&str] = &[
40+
"lowercase",
41+
"UPPERCASE",
42+
"PascalCase",
43+
"camelCase",
44+
"snake_case",
45+
"SCREAMING_SNAKE_CASE",
46+
"kebab-case",
47+
"SCREAMING-KEBAB-CASE",
48+
"Train-Case",
4049
];
4150

4251
impl RenameRule {
43-
/// Apply a renaming rule to an enum variant, returning the version expected in the source.
44-
pub fn apply_to_variant(&self, variant: &str) -> String {
45-
match *self {
46-
PascalCase => variant.to_owned(),
47-
LowerCase => variant.to_ascii_lowercase(),
48-
UpperCase => variant.to_ascii_uppercase(),
49-
CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
50-
SnakeCase => {
51-
let mut snake = String::new();
52-
for (i, ch) in variant.char_indices() {
53-
if i > 0 && ch.is_uppercase() {
54-
snake.push('_');
55-
}
56-
snake.push(ch.to_ascii_lowercase());
57-
}
58-
snake
59-
}
60-
ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
61-
KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
62-
ScreamingKebabCase => ScreamingSnakeCase
63-
.apply_to_variant(variant)
64-
.replace('_', "-"),
52+
pub fn from_str(rule: &str) -> Option<RenameRule> {
53+
match rule {
54+
"lowercase" => Some(LowerCase),
55+
"UPPERCASE" => Some(UpperCase),
56+
"PascalCase" => Some(PascalCase),
57+
"camelCase" => Some(CamelCase),
58+
"snake_case" => Some(SnakeCase),
59+
"SCREAMING_SNAKE_CASE" => Some(ScreamingSnakeCase),
60+
"kebab-case" => Some(KebabCase),
61+
"SCREAMING-KEBAB-CASE" => Some(ScreamingKebabCase),
62+
"Train-Case" => Some(TrainCase),
63+
_ => None,
6564
}
6665
}
67-
68-
/// Apply a renaming rule to a struct field, returning the version expected in the source.
69-
pub fn apply_to_field(&self, field: &str) -> String {
66+
/// Apply a renaming rule to an enum or struct field, returning the version expected in the source.
67+
pub fn apply_to_field(&self, variant: &str) -> String {
7068
match *self {
71-
LowerCase | SnakeCase => field.to_owned(),
72-
UpperCase => field.to_ascii_uppercase(),
73-
PascalCase => {
74-
let mut pascal = String::new();
75-
let mut capitalize = true;
76-
for ch in field.chars() {
77-
if ch == '_' {
78-
capitalize = true;
79-
} else if capitalize {
80-
pascal.push(ch.to_ascii_uppercase());
81-
capitalize = false;
82-
} else {
83-
pascal.push(ch);
84-
}
85-
}
86-
pascal
87-
}
88-
CamelCase => {
89-
let pascal = PascalCase.apply_to_field(field);
90-
pascal[..1].to_ascii_lowercase() + &pascal[1..]
91-
}
92-
ScreamingSnakeCase => field.to_ascii_uppercase(),
93-
KebabCase => field.replace('_', "-"),
94-
ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"),
69+
LowerCase => variant.to_lowercase(),
70+
UpperCase => variant.to_uppercase(),
71+
PascalCase => variant.to_upper_camel_case(),
72+
CamelCase => variant.to_lower_camel_case(),
73+
SnakeCase => variant.to_snake_case(),
74+
ScreamingSnakeCase => variant.to_shouty_snake_case(),
75+
KebabCase => variant.to_kebab_case(),
76+
ScreamingKebabCase => variant.to_shouty_kebab_case(),
77+
TrainCase => variant.to_train_case(),
9578
}
9679
}
9780
}
9881

9982
#[test]
100-
fn rename_variants() {
83+
fn rename_field() {
10184
for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[
10285
(
10386
"Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
@@ -115,42 +98,11 @@ fn rename_variants() {
11598
("A", "a", "A", "a", "a", "A", "a", "A"),
11699
("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
117100
] {
118-
assert_eq!(LowerCase.apply_to_variant(original), lower);
119-
assert_eq!(UpperCase.apply_to_variant(original), upper);
120-
assert_eq!(PascalCase.apply_to_variant(original), original);
121-
assert_eq!(CamelCase.apply_to_variant(original), camel);
122-
assert_eq!(SnakeCase.apply_to_variant(original), snake);
123-
assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
124-
assert_eq!(KebabCase.apply_to_variant(original), kebab);
125-
assert_eq!(
126-
ScreamingKebabCase.apply_to_variant(original),
127-
screaming_kebab
128-
);
129-
}
130-
}
131-
132-
#[test]
133-
fn rename_fields() {
134-
for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[
135-
(
136-
"outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
137-
),
138-
(
139-
"very_tasty",
140-
"VERY_TASTY",
141-
"VeryTasty",
142-
"veryTasty",
143-
"VERY_TASTY",
144-
"very-tasty",
145-
"VERY-TASTY",
146-
),
147-
("a", "A", "A", "a", "A", "a", "A"),
148-
("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
149-
] {
101+
assert_eq!(LowerCase.apply_to_field(original), lower);
150102
assert_eq!(UpperCase.apply_to_field(original), upper);
151-
assert_eq!(PascalCase.apply_to_field(original), pascal);
103+
assert_eq!(PascalCase.apply_to_field(original), original);
152104
assert_eq!(CamelCase.apply_to_field(original), camel);
153-
assert_eq!(SnakeCase.apply_to_field(original), original);
105+
assert_eq!(SnakeCase.apply_to_field(original), snake);
154106
assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
155107
assert_eq!(KebabCase.apply_to_field(original), kebab);
156108
assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);

postgres-derive/src/enums.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl Variant {
2222

2323
// variant level name override takes precendence over container level rename_all override
2424
let name = overrides.name.unwrap_or_else(|| match rename_all {
25-
Some(rule) => rule.apply_to_variant(&raw.ident.to_string()),
25+
Some(rule) => rule.apply_to_field(&raw.ident.to_string()),
2626
None => raw.ident.to_string(),
2727
});
2828
Ok(Variant {

postgres-derive/src/overrides.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,19 @@ impl Overrides {
5656
if name_override {
5757
overrides.name = Some(value);
5858
} else if rename_all_override {
59-
let rename_rule = RENAME_RULES
60-
.iter()
61-
.find(|rule| rule.0 == value)
62-
.map(|val| val.1)
63-
.ok_or_else(|| {
64-
Error::new_spanned(
65-
&meta.value,
66-
format!(
67-
"invalid rename_all rule, expected one of: {}",
68-
RENAME_RULES
69-
.iter()
70-
.map(|rule| format!("\"{}\"", rule.0))
71-
.collect::<Vec<_>>()
72-
.join(", ")
73-
),
74-
)
75-
})?;
59+
let rename_rule = RenameRule::from_str(&value).ok_or_else(|| {
60+
Error::new_spanned(
61+
&meta.value,
62+
format!(
63+
"invalid rename_all rule, expected one of: {}",
64+
RENAME_RULES
65+
.iter()
66+
.map(|rule| format!("\"{}\"", rule))
67+
.collect::<Vec<_>>()
68+
.join(", ")
69+
),
70+
)
71+
})?;
7672

7773
overrides.rename_all = Some(rename_rule);
7874
}

0 commit comments

Comments
 (0)