implicit_trait/
lib.rs

1use proc_macro::TokenStream;
2use syn::{parse_macro_input, ItemImpl, ImplItem, AttributeArgs};
3use quote::{quote};
4
5#[proc_macro_attribute]
6pub fn implicit_trait(args: TokenStream, input: TokenStream) -> TokenStream {
7    let item = parse_macro_input!(input as ItemImpl);
8    let args = parse_macro_input!(args as AttributeArgs);
9    let mut vis = quote!();
10    for arg in args.into_iter() {
11        match arg {
12            syn::NestedMeta::Meta(syn::Meta::Path(path)) => {
13                if path.is_ident("pub") {
14                    vis = quote! { pub };
15                } else {
16                    panic!("Only 'pub' is allowed as an argument to implicit_trait");
17                }
18            }
19            _ => panic!("Only 'pub' is allowed as an argument to implicit_trait"),
20        }
21    }
22    let trait_name = &item.trait_.as_ref().unwrap().1;
23    let declarations = item.items.iter().map(|item| {
24        match item {
25            ImplItem::Method(method) => {
26                let sig = &method.sig;
27                quote! {
28                    #sig;
29                }
30            }
31            _ => panic!("Only methods are allowed in an implicit trait"),
32        }
33    });
34    (quote! {
35        #vis trait #trait_name {
36            #(#declarations)*
37        }
38        #item
39    }).into()
40}