Heavily refactored rename_all and switched to SCREAMING_SNAKE_CASE.

This commit is contained in:
Michael Mokrysz
2017-02-23 23:12:48 +00:00
parent fc94c5399a
commit 3b59d47e07
2 changed files with 60 additions and 45 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ impl<'a> Item<'a> {
field.attrs.rename_by_rule(variant.attrs.rename_all()); field.attrs.rename_by_rule(variant.attrs.rename_all());
} }
} }
}, }
Body::Struct(_, ref mut fields) => { Body::Struct(_, ref mut fields) => {
for field in fields { for field in fields {
field.attrs.rename_by_rule(attrs.rename_all()); field.attrs.rename_by_rule(attrs.rename_all());
+59 -44
View File
@@ -3,6 +3,7 @@ use syn;
use syn::MetaItem::{List, NameValue, Word}; use syn::MetaItem::{List, NameValue, Word};
use syn::NestedMetaItem::{Literal, MetaItem}; use syn::NestedMetaItem::{Literal, MetaItem};
use inflector::Inflector; use inflector::Inflector;
use std::str::FromStr;
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
// are `attr::Item::from_ast`, `attr::Variant::from_ast`, and // are `attr::Item::from_ast`, `attr::Variant::from_ast`, and
@@ -87,29 +88,45 @@ impl Name {
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum RenameAll { pub enum RenameRule {
/// Don't apply a default rename rule.
None, None,
/// Rename fields to "PascalCase" style. By Rust coding standards this is the default. /// Rename direct children to "PascalCase" style, as typically used for enum variants.
PascalCase, PascalCase,
/// Rename fields to "snake_case" style. /// Rename direct children to "kebabCase" style.
LowerSnakeCase,
/// Rename fields to "SNAKE_CASE" style.
UpperSnakeCase,
/// Rename fields to "kebab-case" style.
KebabCase,
/// Rename fields to "kebabCase" style.
CamelCase, CamelCase,
/// Rename direct children to "snake_case" style, as commonly used for fields.
SnakeCase,
/// Rename direct children to "SNAKE_CASE" style, as commonly used for constants.
ScreamingSnakeCase,
/// Rename direct children to "kebab-case" style.
KebabCase,
} }
impl RenameAll { impl RenameRule {
pub fn apply(&self, name: String) -> String { pub fn apply(&self, name: String) -> String {
match *self { match *self {
RenameAll::None => name, RenameRule::None => name,
RenameAll::PascalCase => name.to_pascal_case(), RenameRule::PascalCase => name.to_pascal_case(),
RenameAll::LowerSnakeCase => name.to_snake_case(), RenameRule::CamelCase => name.to_camel_case(),
RenameAll::UpperSnakeCase => name.to_screaming_snake_case(), RenameRule::SnakeCase => name.to_snake_case(),
RenameAll::KebabCase => name.to_kebab_case(), RenameRule::ScreamingSnakeCase => name.to_screaming_snake_case(),
RenameAll::CamelCase => name.to_camel_case(), RenameRule::KebabCase => name.to_kebab_case(),
}
}
}
impl FromStr for RenameRule {
type Err = String;
fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
match rename_all_str {
"PascalCase" => Ok(RenameRule::PascalCase),
"camelCase" => Ok(RenameRule::CamelCase),
"snake_case" => Ok(RenameRule::SnakeCase),
"SCREAMING_SNAKE_CASE" => Ok(RenameRule::ScreamingSnakeCase),
"kebab-case" => Ok(RenameRule::KebabCase),
other => Err(other.to_string()),
} }
} }
} }
@@ -120,7 +137,7 @@ pub struct Item {
name: Name, name: Name,
deny_unknown_fields: bool, deny_unknown_fields: bool,
default: Default, default: Default,
rename_all: RenameAll, rename_all: RenameRule,
ser_bound: Option<Vec<syn::WherePredicate>>, ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>, de_bound: Option<Vec<syn::WherePredicate>>,
tag: EnumTag, tag: EnumTag,
@@ -194,15 +211,12 @@ impl Item {
// Parse `#[serde(rename_all="foo")]` // Parse `#[serde(rename_all="foo")]`
MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => { MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
// The path possibility defies a simple IntoString implementation. match RenameRule::from_str(s.as_str()) {
match s.as_str() { Ok(rename_rule) => rename_all.set(rename_rule),
"snake_case" => rename_all.set(RenameAll::LowerSnakeCase), Err(other) => {
"SNAKE_CASE" => rename_all.set(RenameAll::UpperSnakeCase), cx.error(format!("unknown rename rule for #[serde(rename_all \
"kebab-case" => rename_all.set(RenameAll::KebabCase), = {:?})]",
"camelCase" => rename_all.set(RenameAll::CamelCase), other))
"PascalCase" => rename_all.set(RenameAll::PascalCase),
_ => {
cx.error(format!("unknown rename rule for #[serde(rename_all = \"{:?}\")]", s))
} }
} }
} }
@@ -292,7 +306,8 @@ impl Item {
content.set(s); content.set(s);
} }
syn::Body::Struct(_) => { syn::Body::Struct(_) => {
cx.error("#[serde(content = \"...\")] can only be used on enums") cx.error("#[serde(content = \"...\")] can only be used on \
enums")
} }
} }
} }
@@ -345,7 +360,10 @@ impl Item {
EnumTag::External EnumTag::External
} }
(false, Some(tag), Some(content)) => { (false, Some(tag), Some(content)) => {
EnumTag::Adjacent { tag: tag, content: content } EnumTag::Adjacent {
tag: tag,
content: content,
}
} }
(true, Some(_), Some(_)) => { (true, Some(_), Some(_)) => {
cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]"); cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
@@ -360,7 +378,7 @@ impl Item {
}, },
deny_unknown_fields: deny_unknown_fields.get(), deny_unknown_fields: deny_unknown_fields.get(),
default: default.get().unwrap_or(Default::None), default: default.get().unwrap_or(Default::None),
rename_all: rename_all.get().unwrap_or(RenameAll::None), rename_all: rename_all.get().unwrap_or(RenameRule::None),
ser_bound: ser_bound.get(), ser_bound: ser_bound.get(),
de_bound: de_bound.get(), de_bound: de_bound.get(),
tag: tag, tag: tag,
@@ -371,7 +389,7 @@ impl Item {
&self.name &self.name
} }
pub fn rename_all(&self) -> &RenameAll { pub fn rename_all(&self) -> &RenameRule {
&self.rename_all &self.rename_all
} }
@@ -402,7 +420,7 @@ pub struct Variant {
name: Name, name: Name,
ser_renamed: bool, ser_renamed: bool,
de_renamed: bool, de_renamed: bool,
rename_all: RenameAll, rename_all: RenameRule,
skip_deserializing: bool, skip_deserializing: bool,
skip_serializing: bool, skip_serializing: bool,
} }
@@ -437,15 +455,12 @@ impl Variant {
// Parse `#[serde(rename_all="foo")]` // Parse `#[serde(rename_all="foo")]`
MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => { MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
// The path possibility defies a simple IntoString implementation. match RenameRule::from_str(s.as_str()) {
match s.as_str() { Ok(rename_rule) => rename_all.set(rename_rule),
"snake_case" => rename_all.set(RenameAll::LowerSnakeCase), Err(other) => {
"SNAKE_CASE" => rename_all.set(RenameAll::UpperSnakeCase), cx.error(format!("unknown rename rule for #[serde(rename_all \
"kebab-case" => rename_all.set(RenameAll::KebabCase), = {:?})]",
"camelCase" => rename_all.set(RenameAll::CamelCase), other))
"PascalCase" => rename_all.set(RenameAll::PascalCase),
_ => {
cx.error(format!("unknown rename rule for #[serde(rename_all = \"{:?}\")]", s))
} }
} }
} }
@@ -482,7 +497,7 @@ impl Variant {
}, },
ser_renamed: ser_renamed, ser_renamed: ser_renamed,
de_renamed: de_renamed, de_renamed: de_renamed,
rename_all: rename_all.get().unwrap_or(RenameAll::None), rename_all: rename_all.get().unwrap_or(RenameRule::None),
skip_deserializing: skip_deserializing.get(), skip_deserializing: skip_deserializing.get(),
skip_serializing: skip_serializing.get(), skip_serializing: skip_serializing.get(),
} }
@@ -492,7 +507,7 @@ impl Variant {
&self.name &self.name
} }
pub fn rename_by_rule(&mut self, rename_rule: &RenameAll) { pub fn rename_by_rule(&mut self, rename_rule: &RenameRule) {
if !self.ser_renamed { if !self.ser_renamed {
self.name.serialize = rename_rule.apply(self.name.serialize.clone()); self.name.serialize = rename_rule.apply(self.name.serialize.clone());
} }
@@ -501,7 +516,7 @@ impl Variant {
} }
} }
pub fn rename_all(&self) -> &RenameAll { pub fn rename_all(&self) -> &RenameRule {
&self.rename_all &self.rename_all
} }
@@ -694,7 +709,7 @@ impl Field {
&self.name &self.name
} }
pub fn rename_by_rule(&mut self, rename_rule: &RenameAll) { pub fn rename_by_rule(&mut self, rename_rule: &RenameRule) {
if !self.ser_renamed { if !self.ser_renamed {
self.name.serialize = rename_rule.apply(self.name.serialize.clone()); self.name.serialize = rename_rule.apply(self.name.serialize.clone());
} }