-
-
Notifications
You must be signed in to change notification settings - Fork 863
Closed
Labels
Description
This stuff:
serde/serde_codegen/src/lib.rs
Lines 199 to 292 in 3a3777a
| fn strip_serde_derives(item: syn::MacroInput) -> (bool, bool, syn::MacroInput) { | |
| let mut ser = false; | |
| let mut de = false; | |
| let item = syn::MacroInput { | |
| attrs: item.attrs.into_iter().flat_map(|attr| { | |
| if attr.is_sugared_doc { | |
| return Some(attr); | |
| } | |
| let (name, nested) = match attr.value { | |
| syn::MetaItem::List(name, nested) => (name, nested), | |
| _ => return Some(attr) | |
| }; | |
| if name != "derive" { | |
| return Some(syn::Attribute { | |
| value: syn::MetaItem::List(name, nested), | |
| is_sugared_doc: false, | |
| }); | |
| } | |
| let rest: Vec<_> = nested.into_iter().filter(|nested| { | |
| match *nested { | |
| syn::MetaItem::Word(ref word) if word == "Serialize" => { | |
| ser = true; | |
| false | |
| } | |
| syn::MetaItem::Word(ref word) if word == "Deserialize" => { | |
| de = true; | |
| false | |
| } | |
| _ => true, | |
| } | |
| }).collect(); | |
| if rest.is_empty() { | |
| None | |
| } else { | |
| Some(syn::Attribute { | |
| value: syn::MetaItem::List(name, rest), | |
| is_sugared_doc: false, | |
| }) | |
| } | |
| }).collect(), | |
| ..item | |
| }; | |
| (ser, de, item) | |
| } | |
| fn strip_serde_attrs(item: syn::MacroInput) -> syn::MacroInput { | |
| syn::MacroInput { | |
| attrs: strip_serde_from_attrs(item.attrs), | |
| body: match item.body { | |
| syn::Body::Enum(variants) => syn::Body::Enum( | |
| variants.into_iter().map(|variant| { | |
| syn::Variant { | |
| ident: variant.ident, | |
| attrs: strip_serde_from_attrs(variant.attrs), | |
| data: strip_serde_from_variant_data(variant.data), | |
| discriminant: variant.discriminant, | |
| } | |
| }).collect() | |
| ), | |
| syn::Body::Struct(variant_data) => syn::Body::Struct( | |
| strip_serde_from_variant_data(variant_data) | |
| ), | |
| }, | |
| ..item | |
| } | |
| } | |
| fn strip_serde_from_variant_data(data: syn::VariantData) -> syn::VariantData { | |
| match data { | |
| syn::VariantData::Struct(fields) => syn::VariantData::Struct( | |
| fields.into_iter().map(strip_serde_from_field).collect() | |
| ), | |
| syn::VariantData::Tuple(fields) => syn::VariantData::Tuple( | |
| fields.into_iter().map(strip_serde_from_field).collect() | |
| ), | |
| syn::VariantData::Unit => syn::VariantData::Unit, | |
| } | |
| } | |
| fn strip_serde_from_field(field: syn::Field) -> syn::Field { | |
| syn::Field { | |
| attrs: strip_serde_from_attrs(field.attrs), | |
| ..field | |
| } | |
| } | |
| fn strip_serde_from_attrs(attrs: Vec<syn::Attribute>) -> Vec<syn::Attribute> { | |
| attrs.into_iter().filter(|attr| { | |
| match attr.value { | |
| syn::MetaItem::List(ref ident, _) => ident != "serde", | |
| _ => true, | |
| } | |
| }).collect() | |
| } |
Here is how libsyntax does it: https://github.com/rust-lang/rust/blob/master/src/libsyntax/fold.rs