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 40 41 42 43 44 45 46 47 48 49 50
extern crate proc_macro; extern crate syn; #[macro_use] extern crate quote; use proc_macro::TokenStream; #[proc_macro_derive(Future)] pub fn future(input: TokenStream) -> TokenStream { let s = input.to_string(); let ast = syn::parse_macro_input(&s).unwrap(); let gen = impl_future(&ast); gen.parse().unwrap() } fn impl_future(ast: &syn::MacroInput) -> quote::Tokens { let name = &ast.ident; match ast.body { syn::Body::Enum(ref variants) => { let constraints = variants.iter().map(|var| { let ty = &var.data.fields()[0].ty; quote! { #ty : Future<Item = It, Error = Err> } }); let types = variants.iter().map(|var| { let t = &var.data.fields()[0].ty; quote! { #t } }); let match_clauses = variants.iter().map(|var| { let var_name = &var.ident; quote! { #name::#var_name(ref mut a) => a.poll() } }); quote! { impl<It, Err, #(#constraints),*> Future for #name<#(#types),*> { type Item = It; type Error = Err; fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> { match *self { #(#match_clauses),* } } } } }, _ => panic!("Only enums can derive EnumFrom") } }