Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions serde_derive/src/internals/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,14 @@ impl<'a> Container<'a> {
match &mut data {
Data::Enum(variants) => {
for variant in variants {
for alias_all_rule in attrs.alias_all_rules() {
variant.attrs.alias_by_rule(*alias_all_rule);
}
variant.attrs.rename_by_rules(attrs.rename_all_rules());
for field in &mut variant.fields {
for alias_all_rule in attrs.alias_all_rules() {
field.attrs.alias_by_rule(*alias_all_rule);
}
field.attrs.rename_by_rules(
variant
.attrs
Expand All @@ -93,6 +99,9 @@ impl<'a> Container<'a> {
}
Data::Struct(_, fields) => {
for field in fields {
for alias_all_rule in attrs.alias_all_rules() {
field.attrs.alias_by_rule(*alias_all_rule);
}
field.attrs.rename_by_rules(attrs.rename_all_rules());
}
}
Expand Down
34 changes: 34 additions & 0 deletions serde_derive/src/internals/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ pub struct Container {
default: Default,
rename_all_rules: RenameAllRules,
rename_all_fields_rules: RenameAllRules,
alias_all_rules: Vec<RenameRule>,
ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>,
tag: TagType,
Expand Down Expand Up @@ -245,6 +246,7 @@ impl Container {
let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL);
let mut rename_all_fields_ser_rule = Attr::none(cx, RENAME_ALL_FIELDS);
let mut rename_all_fields_de_rule = Attr::none(cx, RENAME_ALL_FIELDS);
let mut alias_all_rules = VecAttr::none(cx, ALIAS_ALL);
let mut ser_bound = Attr::none(cx, BOUND);
let mut de_bound = Attr::none(cx, BOUND);
let mut untagged = BoolAttr::none(cx, UNTAGGED);
Expand Down Expand Up @@ -491,6 +493,14 @@ impl Container {
if let Some(s) = get_lit_str(cx, EXPECTING, &meta)? {
expecting.set(&meta.path, s.value());
}
} else if meta.path == ALIAS_ALL {
// #[serde(alias_all = "...")]
if let Some(s) = get_lit_str(cx, ALIAS_ALL, &meta)? {
match RenameRule::from_str(&s.value()) {
Ok(rename_rule) => alias_all_rules.insert(&meta.path, rename_rule),
Err(err) => cx.error_spanned_by(s, err),
}
}
} else {
let path = meta.path.to_token_stream().to_string().replace(' ', "");
return Err(
Expand Down Expand Up @@ -530,6 +540,7 @@ impl Container {
serialize: rename_all_fields_ser_rule.get().unwrap_or(RenameRule::None),
deserialize: rename_all_fields_de_rule.get().unwrap_or(RenameRule::None),
},
alias_all_rules: alias_all_rules.get(),
ser_bound: ser_bound.get(),
de_bound: de_bound.get(),
tag: decide_tag(cx, item, untagged, internal_tag, content),
Expand Down Expand Up @@ -569,6 +580,10 @@ impl Container {
&self.default
}

pub fn alias_all_rules(&self) -> &[RenameRule] {
&self.alias_all_rules
}

pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
self.ser_bound.as_ref().map(|vec| &vec[..])
}
Expand Down Expand Up @@ -943,6 +958,15 @@ impl Variant {
.insert(self.name.deserialize.clone());
}

pub fn alias_by_rule(&mut self, rule: RenameRule) {
let alias_name = rule.apply_to_variant(&self.name.deserialize.value);
let alias = Name {
value: alias_name,
span: self.name.deserialize.span,
};
self.name.deserialize_aliases.insert(alias);
}

pub fn rename_all_rules(&self) -> RenameAllRules {
self.rename_all_rules
}
Expand Down Expand Up @@ -1341,6 +1365,16 @@ impl Field {
pub fn mark_transparent(&mut self) {
self.transparent = true;
}

pub fn alias_by_rule(&mut self, rule: RenameRule) {
// Apply the rename rule to the original field name to create an alias
let alias_name = rule.apply_to_field(&self.name.deserialize.value);
let alias = Name {
value: alias_name,
span: self.name.deserialize.span,
};
self.name.deserialize_aliases.insert(alias);
}
}

type SerAndDe<T> = (Option<T>, Option<T>);
Expand Down
1 change: 1 addition & 0 deletions serde_derive/src/internals/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use syn::{Ident, Path};
pub struct Symbol(&'static str);

pub const ALIAS: Symbol = Symbol("alias");
pub const ALIAS_ALL: Symbol = Symbol("alias_all");
pub const BORROW: Symbol = Symbol("borrow");
pub const BOUND: Symbol = Symbol("bound");
pub const CONTENT: Symbol = Symbol("content");
Expand Down
Loading
Loading