Merge pull request 1447 from vincascm/master

This commit is contained in:
David Tolnay
2018-12-27 15:28:37 -05:00
3 changed files with 105 additions and 22 deletions
+3 -3
View File
@@ -85,12 +85,12 @@ impl<'a> Container<'a> {
match data { match data {
Data::Enum(ref mut variants) => { Data::Enum(ref mut variants) => {
for variant in variants { for variant in variants {
variant.attrs.rename_by_rule(attrs.rename_all()); variant.attrs.rename_by_rules(attrs.rename_all_rules());
for field in &mut variant.fields { for field in &mut variant.fields {
if field.attrs.flatten() { if field.attrs.flatten() {
has_flatten = true; has_flatten = true;
} }
field.attrs.rename_by_rule(variant.attrs.rename_all()); field.attrs.rename_by_rules(variant.attrs.rename_all_rules());
} }
} }
} }
@@ -99,7 +99,7 @@ impl<'a> Container<'a> {
if field.attrs.flatten() { if field.attrs.flatten() {
has_flatten = true; has_flatten = true;
} }
field.attrs.rename_by_rule(attrs.rename_all()); field.attrs.rename_by_rules(attrs.rename_all_rules());
} }
} }
} }
+101 -18
View File
@@ -115,13 +115,18 @@ impl Name {
} }
} }
pub struct RenameAllRules {
serialize: RenameRule,
deserialize: RenameRule,
}
/// Represents struct or enum attribute information. /// Represents struct or enum attribute information.
pub struct Container { pub struct Container {
name: Name, name: Name,
transparent: bool, transparent: bool,
deny_unknown_fields: bool, deny_unknown_fields: bool,
default: Default, default: Default,
rename_all: RenameRule, rename_all_rules: RenameAllRules,
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,
@@ -198,7 +203,8 @@ impl Container {
let mut transparent = BoolAttr::none(cx, "transparent"); let mut transparent = BoolAttr::none(cx, "transparent");
let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields"); let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
let mut default = Attr::none(cx, "default"); let mut default = Attr::none(cx, "default");
let mut rename_all = Attr::none(cx, "rename_all"); let mut rename_all_ser_rule = Attr::none(cx, "rename_all");
let mut rename_all_de_rule = Attr::none(cx, "rename_all");
let mut ser_bound = Attr::none(cx, "bound"); let mut ser_bound = Attr::none(cx, "bound");
let mut de_bound = Attr::none(cx, "bound"); let mut de_bound = Attr::none(cx, "bound");
let mut untagged = BoolAttr::none(cx, "untagged"); let mut untagged = BoolAttr::none(cx, "untagged");
@@ -233,7 +239,10 @@ impl Container {
Meta(NameValue(ref m)) if m.ident == "rename_all" => { Meta(NameValue(ref m)) if m.ident == "rename_all" => {
if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) { if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
match RenameRule::from_str(&s.value()) { match RenameRule::from_str(&s.value()) {
Ok(rename_rule) => rename_all.set(&m.ident, rename_rule), Ok(rename_rule) => {
rename_all_ser_rule.set(&m.ident, rename_rule);
rename_all_de_rule.set(&m.ident, rename_rule);
},
Err(()) => cx.error_spanned_by( Err(()) => cx.error_spanned_by(
s, s,
format!( format!(
@@ -246,6 +255,38 @@ impl Container {
} }
} }
// Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]`
Meta(List(ref m)) if m.ident == "rename_all" => {
if let Ok((ser, de)) = get_renames(cx, &m.nested) {
if let Some(ser) = ser {
match RenameRule::from_str(&ser.value()) {
Ok(rename_rule) => rename_all_ser_rule.set(&m.ident, rename_rule),
Err(()) => cx.error_spanned_by(
ser,
format!(
"unknown rename rule for #[serde(rename_all \
= {:?})]",
ser.value(),
),
),
}
}
if let Some(de) = de {
match RenameRule::from_str(&de.value()) {
Ok(rename_rule) => rename_all_de_rule.set(&m.ident, rename_rule),
Err(()) => cx.error_spanned_by(
de,
format!(
"unknown rename rule for #[serde(rename_all \
= {:?})]",
de.value(),
),
),
}
}
}
}
// Parse `#[serde(transparent)]` // Parse `#[serde(transparent)]`
Meta(Word(ref word)) if word == "transparent" => { Meta(Word(ref word)) if word == "transparent" => {
transparent.set_true(word); transparent.set_true(word);
@@ -469,7 +510,10 @@ impl Container {
transparent: transparent.get(), transparent: transparent.get(),
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(RenameRule::None), rename_all_rules: RenameAllRules {
serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
deserialize: rename_all_de_rule.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: decide_tag(cx, item, untagged, internal_tag, content), tag: decide_tag(cx, item, untagged, internal_tag, content),
@@ -485,8 +529,8 @@ impl Container {
&self.name &self.name
} }
pub fn rename_all(&self) -> &RenameRule { pub fn rename_all_rules(&self) -> &RenameAllRules {
&self.rename_all &self.rename_all_rules
} }
pub fn transparent(&self) -> bool { pub fn transparent(&self) -> bool {
@@ -709,7 +753,7 @@ pub struct Variant {
name: Name, name: Name,
ser_renamed: bool, ser_renamed: bool,
de_renamed: bool, de_renamed: bool,
rename_all: RenameRule, rename_all_rules: RenameAllRules,
ser_bound: Option<Vec<syn::WherePredicate>>, ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>, de_bound: Option<Vec<syn::WherePredicate>>,
skip_deserializing: bool, skip_deserializing: bool,
@@ -726,7 +770,8 @@ impl Variant {
let mut de_name = Attr::none(cx, "rename"); let mut de_name = Attr::none(cx, "rename");
let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing"); let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing"); let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
let mut rename_all = Attr::none(cx, "rename_all"); let mut rename_all_ser_rule = Attr::none(cx, "rename_all");
let mut rename_all_de_rule = Attr::none(cx, "rename_all");
let mut ser_bound = Attr::none(cx, "bound"); let mut ser_bound = Attr::none(cx, "bound");
let mut de_bound = Attr::none(cx, "bound"); let mut de_bound = Attr::none(cx, "bound");
let mut other = BoolAttr::none(cx, "other"); let mut other = BoolAttr::none(cx, "other");
@@ -757,7 +802,10 @@ impl Variant {
Meta(NameValue(ref m)) if m.ident == "rename_all" => { Meta(NameValue(ref m)) if m.ident == "rename_all" => {
if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) { if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
match RenameRule::from_str(&s.value()) { match RenameRule::from_str(&s.value()) {
Ok(rename_rule) => rename_all.set(&m.ident, rename_rule), Ok(rename_rule) => {
rename_all_ser_rule.set(&m.ident, rename_rule);
rename_all_de_rule.set(&m.ident, rename_rule);
},
Err(()) => cx.error_spanned_by( Err(()) => cx.error_spanned_by(
s, s,
format!( format!(
@@ -770,6 +818,38 @@ impl Variant {
} }
} }
// Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]`
Meta(List(ref m)) if m.ident == "rename_all" => {
if let Ok((ser, de)) = get_renames(cx, &m.nested) {
if let Some(ser) = ser {
match RenameRule::from_str(&ser.value()) {
Ok(rename_rule) => rename_all_ser_rule.set(&m.ident, rename_rule),
Err(()) => cx.error_spanned_by(
ser,
format!(
"unknown rename rule for #[serde(rename_all \
= {:?})]",
ser.value(),
),
),
}
}
if let Some(de) = de {
match RenameRule::from_str(&de.value()) {
Ok(rename_rule) => rename_all_de_rule.set(&m.ident, rename_rule),
Err(()) => cx.error_spanned_by(
de,
format!(
"unknown rename rule for #[serde(rename_all \
= {:?})]",
de.value(),
),
),
}
}
}
}
// Parse `#[serde(skip)]` // Parse `#[serde(skip)]`
Meta(Word(ref word)) if word == "skip" => { Meta(Word(ref word)) if word == "skip" => {
skip_serializing.set_true(word); skip_serializing.set_true(word);
@@ -879,7 +959,10 @@ 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(RenameRule::None), rename_all_rules: RenameAllRules {
serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
deserialize: rename_all_de_rule.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(),
skip_deserializing: skip_deserializing.get(), skip_deserializing: skip_deserializing.get(),
@@ -895,17 +978,17 @@ impl Variant {
&self.name &self.name
} }
pub fn rename_by_rule(&mut self, rule: &RenameRule) { pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
if !self.ser_renamed { if !self.ser_renamed {
self.name.serialize = rule.apply_to_variant(&self.name.serialize); self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
} }
if !self.de_renamed { if !self.de_renamed {
self.name.deserialize = rule.apply_to_variant(&self.name.deserialize); self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
} }
} }
pub fn rename_all(&self) -> &RenameRule { pub fn rename_all_rules(&self) -> &RenameAllRules {
&self.rename_all &self.rename_all_rules
} }
pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
@@ -1264,12 +1347,12 @@ impl Field {
&self.name &self.name
} }
pub fn rename_by_rule(&mut self, rule: &RenameRule) { pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
if !self.ser_renamed { if !self.ser_renamed {
self.name.serialize = rule.apply_to_field(&self.name.serialize); self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
} }
if !self.de_renamed { if !self.de_renamed {
self.name.deserialize = rule.apply_to_field(&self.name.deserialize); self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
} }
} }
+1 -1
View File
@@ -10,7 +10,7 @@ use std::str::FromStr;
use self::RenameRule::*; use self::RenameRule::*;
/// The different possible ways to change case of fields in a struct, or variants in an enum. /// The different possible ways to change case of fields in a struct, or variants in an enum.
#[derive(PartialEq)] #[derive(Copy, Clone, PartialEq)]
pub enum RenameRule { pub enum RenameRule {
/// Don't apply a default rename rule. /// Don't apply a default rename rule.
None, None,