-
-
Notifications
You must be signed in to change notification settings - Fork 858
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