Use post-expansion crate to let other custom derives see serde attrs

This commit is contained in:
David Tolnay 2016-10-16 23:17:17 -07:00
parent 532b950971
commit a9b6cbb8b3
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
4 changed files with 13 additions and 51 deletions

View File

@ -22,6 +22,7 @@ with-syn = []
[dependencies]
clippy = { version = "^0.*", optional = true }
post-expansion = "0.0.2"
quote = "0.3"
serde_codegen_internals = { version = "=0.10.0", default-features = false, path = "../serde_codegen_internals" }
syn = { version = "0.9", features = ["aster", "visit"] }

View File

@ -27,6 +27,9 @@ extern crate syn;
#[macro_use]
extern crate quote;
#[cfg(feature = "with-syn")]
extern crate post_expansion;
#[cfg(feature = "with-syntex")]
use std::path::Path;
@ -193,7 +196,7 @@ pub fn expand_single_item(item: &str) -> Result<String, String> {
} else {
None::<quote::Tokens>
};
let syn_item = strip_serde_attrs(syn_item);
let syn_item = post_expansion::strip_attrs_later(syn_item, &["serde"], "serde");
return Ok(quote!(#expanded_ser #expanded_de #syn_item).to_string());
fn strip_serde_derives(item: syn::MacroInput) -> (bool, bool, syn::MacroInput) {
@ -242,54 +245,4 @@ pub fn expand_single_item(item: &str) -> Result<String, String> {
};
(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()
}
}

View File

@ -14,6 +14,9 @@ include = ["Cargo.toml", "src/**/*.rs"]
name = "serde_derive"
proc-macro = true
[dependencies]
post-expansion = "0.0.2"
[dependencies.serde_codegen]
version = "=0.8.13"
path = "../serde_codegen"

View File

@ -4,6 +4,9 @@
extern crate proc_macro;
extern crate serde_codegen;
#[macro_use]
extern crate post_expansion;
use proc_macro::TokenStream;
#[proc_macro_derive(Serialize)]
@ -23,3 +26,5 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream {
Err(msg) => panic!(msg),
}
}
register_post_expansion!(PostExpansion_serde);