implicit_clone_derive/
lib.rs1use quote::quote;
2
3#[proc_macro_derive(ImplicitClone)]
4pub fn derive_implicit_clone(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
5 let syn::DeriveInput {
6 ident, generics, ..
7 } = syn::parse_macro_input!(item as syn::DeriveInput);
8 let (_impl_generics, ty_generics, where_clause) = generics.split_for_impl();
9 let generics = generics
10 .params
11 .iter()
12 .map(|param| match param {
13 syn::GenericParam::Type(syn::TypeParam {
14 attrs,
15 ident,
16 colon_token: _,
17 bounds,
18 eq_token,
19 default,
20 }) => {
21 let bounds = bounds
22 .iter()
23 .map(|bound| quote! { #bound })
24 .chain(std::iter::once(quote! { ::implicit_clone::ImplicitClone }))
25 .collect::<Vec<_>>();
26 quote! {
27 #(#attrs)* #ident: #(#bounds)+* #eq_token #default
28 }
29 }
30 _ => quote! { #param },
31 })
32 .collect::<Vec<_>>();
33 let generics = if generics.is_empty() {
34 quote! {}
35 } else {
36 quote! {
37 <#(#generics),*>
38 }
39 };
40 let res = quote! {
41 impl #generics ::implicit_clone::ImplicitClone for #ident #ty_generics #where_clause {}
42 };
43 res.into()
44}