#![warn(missing_docs)]
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;
use proc_macro::TokenStream;
use syn::Ty::Path;
use syn::{Body, VariantData};
#[proc_macro_derive(StructIterator)]
pub fn struct_iterator(input: TokenStream) -> TokenStream {
let s = input.to_string();
let ast = syn::parse_macro_input(&s).unwrap();
let gen = match ast.body {
Body::Enum(_) => panic!("Enum unsporrted."),
Body::Struct(ref fields) => impl_struct_iter(fields),
};
gen.parse().unwrap()
}
fn impl_struct_iter(fields: &VariantData) -> quote::Tokens {
let mut idents = Vec::new();
match fields {
VariantData::Tuple(ref fields) => {
for (_, field) in fields.iter().enumerate() {
match &field.ty {
Path(_, ref f) => {
let ident = &f.segments[0].ident;
idents.push(ident);
}
_ => panic!("Unexpected tuple field."),
}
}
}
_ => panic!("Unsupported variant data."),
}
let mut res = Vec::new();
for i in 0..=10 {
for x in idents.iter() {
let size = i as usize;
res.push(quote! {
impl_zero!(
[#x; #size], [<#x>::default(); #size]
);
});
}
}
quote! {
#(#res)*
}
}