1use proc_macro_error2::abort;
2use quote::quote;
3use syn::spanned::Spanned as _;
4
5#[proc_macro_error2::proc_macro_error]
6#[proc_macro_attribute]
7pub fn single_trait_impl(
8 _args: proc_macro::TokenStream,
9 input: proc_macro::TokenStream,
10) -> proc_macro::TokenStream {
11 let root_impl = syn::parse_macro_input!(input as syn::ItemImpl);
12 let root_span = root_impl.span();
13 let trait_ = match &root_impl.trait_ {
14 Some((_, path, _)) => path,
15 None => abort!(root_span, "this only works on trait impls"),
16 };
17
18 let mut trait_functions = Vec::with_capacity(root_impl.items.len());
19 for item in &root_impl.items {
20 let mut method = match item {
21 syn::ImplItem::Method(m) => m.clone(),
22 _ => abort!(item, "unsupported item"),
23 };
24
25 method.block.stmts = vec![syn::Stmt::Item(syn::Item::Verbatim(quote! {;}))];
26
27 trait_functions.push(method);
28 }
29
30 proc_macro::TokenStream::from(quote! {
31 pub trait #trait_ {
32 #(#trait_functions)*
33 }
34
35 #root_impl
36 })
37}