1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
extern crate proc_macro;
extern crate proc_macro2;
use quote::quote;
use syn;
#[proc_macro_derive(HeapSpace)]
pub fn heap_space(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast: syn::DeriveInput = syn::parse(input).unwrap();
let type_name = ast.ident;
let (impl_generics, type_generics, where_clause) = ast.generics.split_for_impl();
let block = match ast.data {
syn::Data::Struct(ref data_struct) => data_struct
.fields
.iter()
.map(|field| {
let field_name = &field.ident;
quote!(self.#field_name.heap_space())
})
.fold(quote!(0), |a, b| quote!(#a + #b)),
syn::Data::Enum(ref data_enum) => data_enum
.variants
.iter()
.map(|field| quote!(self.#field.ident.heap_space()))
.fold(quote!(0), |a, b| quote!(#a + #b)),
syn::Data::Union(ref _data_union) => panic!("not implemented for unions"),
};
let implementation = quote!(
impl #impl_generics
HeapSpace for #type_name #type_generics #where_clause {
fn heap_space(&self) -> usize {
#block
}
}
);
implementation.into()
}