Replaced case conversion with heck
This commit is contained in:
parent
bc8ad8aee6
commit
d509b3bc52
@ -15,3 +15,4 @@ test = false
|
||||
syn = "2.0"
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
heck = "0.4"
|
@ -1,6 +1,11 @@
|
||||
#[allow(deprecated, unused_imports)]
|
||||
use std::ascii::AsciiExt;
|
||||
|
||||
use heck::{
|
||||
ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase, ToTrainCase,
|
||||
ToUpperCamelCase,
|
||||
};
|
||||
|
||||
use self::RenameRule::*;
|
||||
|
||||
/// The different possible ways to change case of fields in a struct, or variants in an enum.
|
||||
@ -26,78 +31,56 @@ pub enum RenameRule {
|
||||
KebabCase,
|
||||
/// Rename direct children to "SCREAMING-KEBAB-CASE" style.
|
||||
ScreamingKebabCase,
|
||||
|
||||
/// Rename direct children to "Train-Case" style.
|
||||
TrainCase,
|
||||
}
|
||||
|
||||
pub static RENAME_RULES: &[(&str, RenameRule)] = &[
|
||||
("lowercase", LowerCase),
|
||||
("UPPERCASE", UpperCase),
|
||||
("PascalCase", PascalCase),
|
||||
("camelCase", CamelCase),
|
||||
("snake_case", SnakeCase),
|
||||
("SCREAMING_SNAKE_CASE", ScreamingSnakeCase),
|
||||
("kebab-case", KebabCase),
|
||||
("SCREAMING-KEBAB-CASE", ScreamingKebabCase),
|
||||
pub const RENAME_RULES: &[&str] = &[
|
||||
"lowercase",
|
||||
"UPPERCASE",
|
||||
"PascalCase",
|
||||
"camelCase",
|
||||
"snake_case",
|
||||
"SCREAMING_SNAKE_CASE",
|
||||
"kebab-case",
|
||||
"SCREAMING-KEBAB-CASE",
|
||||
"Train-Case",
|
||||
];
|
||||
|
||||
impl RenameRule {
|
||||
/// Apply a renaming rule to an enum variant, returning the version expected in the source.
|
||||
pub fn apply_to_variant(&self, variant: &str) -> String {
|
||||
match *self {
|
||||
PascalCase => variant.to_owned(),
|
||||
LowerCase => variant.to_ascii_lowercase(),
|
||||
UpperCase => variant.to_ascii_uppercase(),
|
||||
CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
|
||||
SnakeCase => {
|
||||
let mut snake = String::new();
|
||||
for (i, ch) in variant.char_indices() {
|
||||
if i > 0 && ch.is_uppercase() {
|
||||
snake.push('_');
|
||||
}
|
||||
snake.push(ch.to_ascii_lowercase());
|
||||
}
|
||||
snake
|
||||
}
|
||||
ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
|
||||
KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
|
||||
ScreamingKebabCase => ScreamingSnakeCase
|
||||
.apply_to_variant(variant)
|
||||
.replace('_', "-"),
|
||||
pub fn from_str(rule: &str) -> Option<RenameRule> {
|
||||
match rule {
|
||||
"lowercase" => Some(LowerCase),
|
||||
"UPPERCASE" => Some(UpperCase),
|
||||
"PascalCase" => Some(PascalCase),
|
||||
"camelCase" => Some(CamelCase),
|
||||
"snake_case" => Some(SnakeCase),
|
||||
"SCREAMING_SNAKE_CASE" => Some(ScreamingSnakeCase),
|
||||
"kebab-case" => Some(KebabCase),
|
||||
"SCREAMING-KEBAB-CASE" => Some(ScreamingKebabCase),
|
||||
"Train-Case" => Some(TrainCase),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply a renaming rule to a struct field, returning the version expected in the source.
|
||||
pub fn apply_to_field(&self, field: &str) -> String {
|
||||
/// Apply a renaming rule to an enum or struct field, returning the version expected in the source.
|
||||
pub fn apply_to_field(&self, variant: &str) -> String {
|
||||
match *self {
|
||||
LowerCase | SnakeCase => field.to_owned(),
|
||||
UpperCase => field.to_ascii_uppercase(),
|
||||
PascalCase => {
|
||||
let mut pascal = String::new();
|
||||
let mut capitalize = true;
|
||||
for ch in field.chars() {
|
||||
if ch == '_' {
|
||||
capitalize = true;
|
||||
} else if capitalize {
|
||||
pascal.push(ch.to_ascii_uppercase());
|
||||
capitalize = false;
|
||||
} else {
|
||||
pascal.push(ch);
|
||||
}
|
||||
}
|
||||
pascal
|
||||
}
|
||||
CamelCase => {
|
||||
let pascal = PascalCase.apply_to_field(field);
|
||||
pascal[..1].to_ascii_lowercase() + &pascal[1..]
|
||||
}
|
||||
ScreamingSnakeCase => field.to_ascii_uppercase(),
|
||||
KebabCase => field.replace('_', "-"),
|
||||
ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"),
|
||||
LowerCase => variant.to_lowercase(),
|
||||
UpperCase => variant.to_uppercase(),
|
||||
PascalCase => variant.to_upper_camel_case(),
|
||||
CamelCase => variant.to_lower_camel_case(),
|
||||
SnakeCase => variant.to_snake_case(),
|
||||
ScreamingSnakeCase => variant.to_shouty_snake_case(),
|
||||
KebabCase => variant.to_kebab_case(),
|
||||
ScreamingKebabCase => variant.to_shouty_kebab_case(),
|
||||
TrainCase => variant.to_train_case(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rename_variants() {
|
||||
fn rename_field() {
|
||||
for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[
|
||||
(
|
||||
"Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
|
||||
@ -115,42 +98,11 @@ fn rename_variants() {
|
||||
("A", "a", "A", "a", "a", "A", "a", "A"),
|
||||
("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
|
||||
] {
|
||||
assert_eq!(LowerCase.apply_to_variant(original), lower);
|
||||
assert_eq!(UpperCase.apply_to_variant(original), upper);
|
||||
assert_eq!(PascalCase.apply_to_variant(original), original);
|
||||
assert_eq!(CamelCase.apply_to_variant(original), camel);
|
||||
assert_eq!(SnakeCase.apply_to_variant(original), snake);
|
||||
assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
|
||||
assert_eq!(KebabCase.apply_to_variant(original), kebab);
|
||||
assert_eq!(
|
||||
ScreamingKebabCase.apply_to_variant(original),
|
||||
screaming_kebab
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rename_fields() {
|
||||
for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[
|
||||
(
|
||||
"outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
|
||||
),
|
||||
(
|
||||
"very_tasty",
|
||||
"VERY_TASTY",
|
||||
"VeryTasty",
|
||||
"veryTasty",
|
||||
"VERY_TASTY",
|
||||
"very-tasty",
|
||||
"VERY-TASTY",
|
||||
),
|
||||
("a", "A", "A", "a", "A", "a", "A"),
|
||||
("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
|
||||
] {
|
||||
assert_eq!(LowerCase.apply_to_field(original), lower);
|
||||
assert_eq!(UpperCase.apply_to_field(original), upper);
|
||||
assert_eq!(PascalCase.apply_to_field(original), pascal);
|
||||
assert_eq!(PascalCase.apply_to_field(original), original);
|
||||
assert_eq!(CamelCase.apply_to_field(original), camel);
|
||||
assert_eq!(SnakeCase.apply_to_field(original), original);
|
||||
assert_eq!(SnakeCase.apply_to_field(original), snake);
|
||||
assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
|
||||
assert_eq!(KebabCase.apply_to_field(original), kebab);
|
||||
assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
|
||||
|
@ -22,7 +22,7 @@ impl Variant {
|
||||
|
||||
// variant level name override takes precendence over container level rename_all override
|
||||
let name = overrides.name.unwrap_or_else(|| match rename_all {
|
||||
Some(rule) => rule.apply_to_variant(&raw.ident.to_string()),
|
||||
Some(rule) => rule.apply_to_field(&raw.ident.to_string()),
|
||||
None => raw.ident.to_string(),
|
||||
});
|
||||
Ok(Variant {
|
||||
|
@ -56,23 +56,19 @@ impl Overrides {
|
||||
if name_override {
|
||||
overrides.name = Some(value);
|
||||
} else if rename_all_override {
|
||||
let rename_rule = RENAME_RULES
|
||||
.iter()
|
||||
.find(|rule| rule.0 == value)
|
||||
.map(|val| val.1)
|
||||
.ok_or_else(|| {
|
||||
Error::new_spanned(
|
||||
&meta.value,
|
||||
format!(
|
||||
"invalid rename_all rule, expected one of: {}",
|
||||
RENAME_RULES
|
||||
.iter()
|
||||
.map(|rule| format!("\"{}\"", rule.0))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
)
|
||||
})?;
|
||||
let rename_rule = RenameRule::from_str(&value).ok_or_else(|| {
|
||||
Error::new_spanned(
|
||||
&meta.value,
|
||||
format!(
|
||||
"invalid rename_all rule, expected one of: {}",
|
||||
RENAME_RULES
|
||||
.iter()
|
||||
.map(|rule| format!("\"{}\"", rule))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
)
|
||||
})?;
|
||||
|
||||
overrides.rename_all = Some(rename_rule);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user