Add ignore and project attributes

This commit is contained in:
John Kåre Alsaker 2018-12-16 04:44:12 +01:00
parent 70156fbb75
commit 10d2008c51
2 changed files with 61 additions and 5 deletions

View File

@ -1,13 +1,69 @@
use synstructure;
use syn;
use proc_macro2;
use syn::{self, Meta, NestedMeta};
use proc_macro2::{self, Ident, Span};
struct Attributes {
ignore: bool,
project: Option<String>,
}
fn parse_attributes(field: &syn::Field) -> Attributes {
let mut attrs = Attributes {
ignore: false,
project: None,
};
for attr in &field.attrs {
if let Ok(meta) = attr.parse_meta() {
if &meta.name().to_string() != "stable_hasher" {
continue;
}
let mut any_attr = false;
if let Meta::List(list) = meta {
for nested in list.nested.iter() {
if let NestedMeta::Meta(meta) = nested {
if &meta.name().to_string() == "ignore" {
attrs.ignore = true;
any_attr = true;
}
if &meta.name().to_string() == "project" {
if let Meta::List(list) = meta {
if let Some(nested) = list.nested.iter().next() {
if let NestedMeta::Meta(meta) = nested {
attrs.project = Some(meta.name().to_string());
any_attr = true;
}
}
}
}
}
}
}
if !any_attr {
panic!("error parsing stable_hasher");
}
}
}
attrs
}
pub fn hash_stable_derive(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
let generic: syn::GenericParam = parse_quote!('__ctx);
s.add_bounds(synstructure::AddBounds::Generics);
s.add_impl_generic(generic);
let body = s.each(|bi| quote!{
::rustc_data_structures::stable_hasher::HashStable::hash_stable(#bi, __hcx, __hasher);
let body = s.each(|bi| {
let attrs = parse_attributes(bi.ast());
if attrs.ignore {
quote!{}
} else if let Some(project) = attrs.project {
let project = Ident::new(&project, Span::call_site());
quote!{
&#bi.#project.hash_stable(__hcx, __hasher);
}
} else {
quote!{
#bi.hash_stable(__hcx, __hasher);
}
}
});
let discriminant = match s.ast().data {

View File

@ -11,4 +11,4 @@ extern crate proc_macro2;
mod hash_stable;
decl_derive!([HashStable] => hash_stable::hash_stable_derive);
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);