callback_trait/
lib.rs

1use proc_macro2::{Ident, TokenStream};
2use quote::{quote};
3use syn::{FnArg, GenericParam, Generics, ItemTrait, Lifetime, parse_macro_input, Pat, PathArguments, ReturnType, Signature, Token, TraitItem, Type, TypeParamBound, WhereClause};
4use syn::__private::Span;
5use syn::punctuated::Punctuated;
6use syn::token::SelfValue;
7
8use syn::parse::{Error, Parse, ParseStream};
9
10#[derive(Copy, Clone)]
11struct Args {
12    pub local: bool,
13}
14
15mod kw {
16    syn::custom_keyword!(Send);
17}
18
19impl Parse for Args {
20    fn parse(input: ParseStream) -> syn::Result<Self> {
21        match try_parse(input) {
22            Ok(args) if input.is_empty() => Ok(args),
23            _ => Err(error()),
24        }
25    }
26}
27
28fn try_parse(input: ParseStream) -> syn::Result<Args> {
29    if input.peek(Token![?]) {
30        input.parse::<Token![?]>()?;
31        input.parse::<kw::Send>()?;
32        Ok(Args { local: true })
33    } else {
34        Ok(Args { local: false })
35    }
36}
37
38fn error() -> Error {
39    let msg = "expected #[async_trait] or #[async_trait(?Send)]";
40    Error::new(Span::call_site(), msg)
41}
42
43#[proc_macro_attribute]
44pub fn callback_trait(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
45    let attr = parse_macro_input!(attr as Args);
46    let input = parse_macro_input!(item as ItemTrait);
47    impl_macro(input, true, attr.local).unwrap_or_else(to_compile_errors).into()
48}
49
50#[proc_macro_attribute]
51pub fn unsafe_callback_trait(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
52    let attr = parse_macro_input!(attr as Args);
53    let input = parse_macro_input!(item as ItemTrait);
54    impl_macro(input, false, attr.local).unwrap_or_else(to_compile_errors).into()
55}
56
57fn impl_macro(input: ItemTrait, is_safe: bool, is_local: bool) -> Result<TokenStream, Vec<syn::Error>> {
58    let name = &input.ident;
59    let original_generics = &input.generics;
60    let items = &input.items;
61    let func_items = items.iter().filter(|item| {
62        if let TraitItem::Fn(_) = item {
63            true
64        } else {
65            false
66        }
67    }).collect::<Vec<_>>();
68    let unfunc_items = items.iter().filter(|item| {
69        if let TraitItem::Fn(_) = item {
70            false
71        } else {
72            true
73        }
74    }).collect::<Vec<_>>();
75    let func_count = func_items.len();
76    if func_count != 1 {
77        return Err(vec![syn::Error::new_spanned(
78            input,
79            "expected exactly one method",
80        )]);
81    }
82    let (func_attr, func_sign) = if let TraitItem::Fn(func_item) = &func_items[0] {
83        (&func_item.attrs, &func_item.sig)
84    } else {
85        unreachable!()
86    };
87
88
89    let func_proc = generate_func_impl(func_sign, is_safe);
90    let generics = generate_generics(func_sign, original_generics, is_safe, is_local);
91
92    let async_trait = if func_sign.asyncness.is_some() {
93        if is_local {
94            quote! {#[async_trait::async_trait(?Send)]}
95        } else {
96            quote! {#[async_trait::async_trait]}
97        }
98    } else {
99        quote! {}
100    };
101    let where_clause = &generics.where_clause;
102    let expanded = quote! {
103            #async_trait
104            #input
105
106            #async_trait
107            impl #generics #name #original_generics for ______F___ #where_clause {
108                #(#unfunc_items)*
109                #(#func_attr)*
110                #func_sign {
111                    #func_proc
112                }
113            }
114        };
115    Ok(expanded)
116}
117
118fn is_async_trait_impl(ty: &Box<Type>) -> bool {
119    if let Type::Path(p) = ty.as_ref() {
120        for seg in p.path.segments.iter() {
121            if seg.ident.to_string() == "Pin" {
122                if let PathArguments::AngleBracketed(arg) = &seg.arguments {
123                    for sub_arg in arg.args.iter() {
124                        if let syn::GenericArgument::Type(ty) = sub_arg {
125                            if let Type::Path(p) = ty {
126                                for seg in p.path.segments.iter() {
127                                    if seg.ident.to_string() == "Box" {
128                                        if let PathArguments::AngleBracketed(arg) = &seg.arguments {
129                                            for sub_arg in arg.args.iter() {
130                                                if let syn::GenericArgument::Type(ty) = sub_arg {
131                                                    if let Type::TraitObject(ty_trait) = ty {
132                                                        for bound in ty_trait.bounds.iter() {
133                                                            if let TypeParamBound::Trait(trait_bound) = bound {
134                                                                for seg in trait_bound.path.segments.iter() {
135                                                                    if seg.ident.to_string() == "Future" {
136                                                                        return true
137                                                                    }
138                                                                }
139                                                            }
140                                                        }
141                                                    }
142                                                }
143                                            }
144                                        }
145                                    }
146                                }
147                            }
148                        }
149                    }
150                }
151            }
152        }
153    }
154    false
155}
156
157fn get_async_trait_furture_bounds(ty: &Box<Type>, is_local: bool) -> Option<Punctuated<TypeParamBound, Token![+]>> {
158    if let Type::Path(p) = ty.as_ref() {
159        for seg in p.path.segments.iter() {
160            if seg.ident.to_string() == "Pin" {
161                if let PathArguments::AngleBracketed(arg) = &seg.arguments {
162                    for sub_arg in arg.args.iter() {
163                        if let syn::GenericArgument::Type(ty) = sub_arg {
164                            if let Type::Path(p) = ty {
165                                for seg in p.path.segments.iter() {
166                                    if seg.ident.to_string() == "Box" {
167                                        if let PathArguments::AngleBracketed(arg) = &seg.arguments {
168                                            for sub_arg in arg.args.iter() {
169                                                if let syn::GenericArgument::Type(ty) = sub_arg {
170                                                    if let Type::TraitObject(ty_trait) = ty {
171                                                        for bound in ty_trait.bounds.iter() {
172                                                            if let TypeParamBound::Trait(trait_bound) = bound {
173                                                                for seg in trait_bound.path.segments.iter() {
174                                                                    if seg.ident.to_string() == "Future" {
175                                                                        let mut ty = Box::new(ty.clone());
176                                                                        if let Type::TraitObject(ty_trait) = ty.as_mut() {
177                                                                            if !is_local {
178                                                                                for bound in ty_trait.bounds.iter_mut() {
179                                                                                    if let TypeParamBound::Lifetime(lifetime) = bound {
180                                                                                        lifetime.apostrophe = Span::call_site();
181                                                                                        lifetime.ident = Ident::new("static", Span::call_site());
182                                                                                    }
183                                                                                }
184                                                                                return Some(ty_trait.bounds.clone());
185                                                                            } else {
186                                                                                return Some(ty_trait.bounds.iter().filter(|bound| {
187                                                                                    if let TypeParamBound::Lifetime(_) = bound {
188                                                                                        false
189                                                                                    } else {
190                                                                                        true
191                                                                                    }
192                                                                                }).cloned().collect::<Punctuated<TypeParamBound, Token![+]>>());
193                                                                            }
194                                                                        }
195                                                                    }
196                                                                }
197                                                            }
198                                                        }
199                                                    }
200                                                }
201                                            }
202                                        }
203                                    }
204                                }
205                            }
206                        }
207                    }
208                }
209            }
210        }
211    }
212    None
213}
214
215fn generate_generics(func: &Signature, generics: &Generics, is_safe: bool, is_local: bool) -> Generics {
216    let rt = if let ReturnType::Type(_, ty) = &func.output {
217        Some(ty.clone())
218    } else {
219        None
220    };
221    let input_types = func.inputs.iter().filter(|item| {
222        if let FnArg::Receiver(_) = item {
223            false
224        } else {
225            true
226        }
227
228    }).map(|item| {
229        match item {
230            FnArg::Receiver(v) => {
231                v.ty.clone()
232            }
233            FnArg::Typed(v) => {
234                let mut ty = v.ty.clone();
235                if let Type::Reference(r) = ty.as_mut() {
236                    if is_safe {
237                        r.lifetime = None;
238                    } else {
239                        r.lifetime = Some(Lifetime::new("'static", Span::call_site()));
240                    }
241                }
242                ty
243            }
244        }
245    }).collect::<Punctuated<Box<Type>, Token![,]>>();
246
247    let mut generics = generics.clone();
248    if func.asyncness.is_none() {
249        generics.params.push(GenericParam::Type(syn::parse_quote! { ______F___ }));
250        if rt.is_some() && is_async_trait_impl(rt.as_ref().unwrap()) {
251            generics.params.push(GenericParam::Type(syn::parse_quote! { ______Fut___ }));
252            let fut = get_async_trait_furture_bounds(rt.as_ref().unwrap(), is_local).unwrap();
253            if generics.where_clause.is_none() {
254                if is_local {
255                    generics.where_clause = Some(syn::parse_quote! {
256                        where ______F___: Fn(#input_types)->______Fut___,
257                        ______Fut___: #fut
258                    });
259                } else {
260                    generics.where_clause = Some(syn::parse_quote! {
261                        where ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(#input_types)->______Fut___,
262                        ______Fut___: #fut
263                    });
264                }
265            } else {
266                let where_clause: WhereClause = if is_local {
267                    syn::parse_quote! {
268                        where ______F___: Fn(#input_types)->______Fut___,
269                        ______Fut___: #fut
270                    }
271                } else {
272                    syn::parse_quote! {
273                        where ______F___: core::marker::Send + core::marker::Sync + 'static +  Fn(#input_types)->______Fut___,
274                        ______Fut___: #fut
275                    }
276                };
277                generics.where_clause.as_mut().unwrap().predicates.extend(where_clause.predicates);
278            }
279        } else {
280            if rt.is_some() {
281                if generics.where_clause.is_none() {
282                    if is_local {
283                        generics.where_clause = Some(syn::parse_quote! {
284                            where ______F___: Fn(#input_types)->#rt
285                        });
286                    } else {
287                        generics.where_clause = Some(syn::parse_quote! {
288                            where ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(#input_types)->#rt
289                        });
290                    }
291                } else {
292                    let where_clause: WhereClause = if is_local {
293                        syn::parse_quote! {
294                            where ______F___: Fn(#input_types)->#rt
295                        }
296                    } else {
297                        syn::parse_quote! {
298                            where ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(#input_types)->#rt
299                        }
300                    };
301                    generics.where_clause.as_mut().unwrap().predicates.extend(where_clause.predicates);
302                }
303            } else {
304                if generics.where_clause.is_none() {
305                    if is_local {
306                        generics.where_clause = Some(syn::parse_quote! {
307                            where ______F___: Fn(#input_types)
308                        });
309                    } else {
310                        generics.where_clause = Some(syn::parse_quote! {
311                            where ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(#input_types)
312                        });
313                    }
314                } else {
315                    let where_clause: WhereClause = if is_local {
316                        syn::parse_quote! {
317                            where ______F___: Fn(#input_types)
318                        }
319                    } else {
320                        syn::parse_quote! {
321                            where ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(#input_types)
322                        }
323                    };
324                    generics.where_clause.as_mut().unwrap().predicates.extend(where_clause.predicates);
325                }
326            }
327        }
328    } else {
329        generics.params.push(GenericParam::Type(syn::parse_quote! { ______F___ }));
330        generics.params.push(GenericParam::Type(syn::parse_quote! { ______Fut___ }));
331        if rt.is_some() {
332            if generics.where_clause.is_none() {
333                if is_local {
334                    generics.where_clause = Some(syn::parse_quote! {
335                        where ______F___: Fn(#input_types)->______Fut___,
336                        ______Fut___: core::future::Future<Output=#rt>
337                    });
338                } else {
339                    generics.where_clause = Some(syn::parse_quote! {
340                        where ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(#input_types)->______Fut___,
341                        ______Fut___: core::future::Future<Output=#rt> + 'static + core::marker::Send
342                    });
343                }
344            } else {
345                let where_clause: WhereClause = if is_local {
346                    syn::parse_quote! {
347                        where ______F___: Fn(#input_types)->______Fut___,
348                        ______Fut___: core::future::Future<Output=#rt>
349                    }
350                } else {
351                    syn::parse_quote! {
352                        where ______F___: core::marker::Send + core::marker::Sync + 'static +  Fn(#input_types)->______Fut___,
353                        ______Fut___: core::future::Future<Output=#rt> + 'static + core::marker::Send
354                    }
355                };
356                generics.where_clause.as_mut().unwrap().predicates.extend(where_clause.predicates);
357            }
358        } else {
359            if generics.where_clause.is_none() {
360                if is_local {
361                    generics.where_clause = Some(syn::parse_quote! {
362                        where ______F___: Fn(#input_types)->______Fut___,
363                        ______Fut___: core::future::Future<Output=()>
364                    });
365                } else {
366                    generics.where_clause = Some(syn::parse_quote! {
367                        where ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(#input_types)->______Fut___,
368                        ______Fut___: core::future::Future<Output=()> + 'static + core::marker::Send
369                    });
370                }
371            } else {
372                let where_clause: WhereClause = if is_local {
373                    syn::parse_quote! {
374                        where ______F___: Fn(#input_types)->______Fut___,
375                        ______Fut___: core::future::Future<Output=()>
376                    }
377                } else {
378                    syn::parse_quote! {
379                        where ______F___: core::marker::Send + core::marker::Sync + 'static +  Fn(#input_types)->______Fut___,
380                        ______Fut___: core::future::Future<Output=()> + 'static + core::marker::Send
381                    }
382                };
383                generics.where_clause.as_mut().unwrap().predicates.extend(where_clause.predicates);
384            }
385        }
386
387    }
388    generics
389}
390
391fn generate_func_impl(func: &Signature, is_safe: bool) -> TokenStream {
392    let types = func.inputs.iter().filter(|item| {
393        if let FnArg::Receiver(_) = item {
394            false
395        } else {
396            true
397        }
398    }).map(|item| {
399        match item {
400            FnArg::Typed(v) => {
401                &v.pat
402            }
403            _ => unreachable!()
404        }
405    }).collect::<Punctuated<&Box<Pat>, Token![,]>>();
406
407    let receivers = func.inputs.iter().filter(|item| {
408        if let FnArg::Receiver(_) = item {
409            true
410        } else {
411            false
412        }
413    }).map(|item| {
414        match item {
415            FnArg::Receiver(v) => {
416                &v.self_token
417            }
418            _ => unreachable!()
419        }
420    }).collect::<Punctuated<&SelfValue, Token![,]>>();
421
422    let static_cast = if is_safe {
423        Vec::new()
424    } else {
425        func.inputs.iter().filter(|item| {
426            match item {
427                FnArg::Receiver(_) => {
428                    false
429                }
430                FnArg::Typed(v) => {
431                    if let Type::Reference(_) = v.ty.as_ref() {
432                        true
433                    } else {
434                        false
435                    }
436                }
437            }
438        }).map(|item| {
439            match item {
440                FnArg::Typed(v) => {
441                    let ty = &v.ty;
442                    let pat = &v.pat;
443                    if let Type::Reference(mut r) = ty.as_ref().clone() {
444                        r.lifetime = Some(Lifetime::new("'static", Span::call_site()));
445                        quote! {
446                            let #pat: #r = unsafe { ::core::mem::transmute(#pat) };
447                        }
448                    } else {
449                        unreachable!()
450                    }
451                }
452                _ => unreachable!()
453            }
454        }).collect::<Vec<TokenStream>>()
455    };
456
457    if func.asyncness.is_none() {
458        let func_impl = if let ReturnType::Type(_, ty) = &func.output {
459            if is_async_trait_impl(ty) {
460                quote! {
461                    Box::pin(async move {
462                        #(#static_cast)*
463                        let fut = (#receivers)(#types);
464                        fut.await
465                    })
466                }
467            } else {
468                quote!{
469                    (#receivers)(#types)
470                }
471            }
472        } else {
473            quote!{
474                (#receivers)(#types)
475            }
476        };
477        quote! {
478            #func_impl
479        }
480    } else {
481        quote! {
482            #(#static_cast)*
483            let fut = (#receivers)(#types);
484            fut.await
485        }
486    }
487}
488fn to_compile_errors(errors: Vec<syn::Error>) -> TokenStream {
489    let compile_errors = errors.iter().map(syn::Error::to_compile_error);
490    quote!(#(#compile_errors)*)
491}
492
493#[test]
494fn test_impl_macro() {
495    let input = syn::parse_quote! {
496        pub trait SampleTrait: 'static + Send + Sync {
497            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
498        }
499    };
500    let result = impl_macro(input, true, false).unwrap();
501    let expected = quote! {
502        #[async_trait::async_trait]
503        pub trait SampleTrait: 'static + Send + Sync {
504            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
505        }
506        #[async_trait::async_trait]
507        impl<______F___, ______Fut___> SampleTrait for ______F___
508            where
509                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&u32, i16) -> ______Fut___,
510                ______Fut___: core::future::Future<Output=Result<(), u32> > + 'static + core::marker::Send
511        {
512            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
513                let fut = (self)(p1, p2);
514                fut.await
515            }
516        }
517    };
518    assert_eq!(result.to_string(), expected.to_string());
519}
520
521#[test]
522fn test_impl_macro2() {
523    let input = syn::parse_quote! {
524        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
525            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
526        }
527    };
528    let result = impl_macro(input, true, false).unwrap();
529    let expected = quote! {
530        #[async_trait::async_trait]
531        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
532            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
533        }
534        #[async_trait::async_trait]
535        impl<T, ______F___, ______Fut___> SampleTrait<T> for ______F___
536            where
537                T: Send,
538                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(u256, u32, T) -> ______Fut___,
539                ______Fut___: core::future::Future<Output=Result<u64, Error> > + 'static + core::marker::Send
540        {
541            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error> {
542                let fut = (self)(p1, p2, t);
543                fut.await
544            }
545        }
546    };
547    assert_eq!(result.to_string(), expected.to_string());
548}
549
550#[test]
551fn test_impl_macro3() {
552    let input = syn::parse_quote! {
553        pub trait SampleTrait: 'static + Send + Sync {
554            #[must_use]
555            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
556            fn call<'life0, 'async_trait>(
557                &'life0 self,
558                p1: u64,
559                p2: u32,
560            ) -> ::core::pin::Pin<
561                Box<
562                    dyn ::core::future::Future<Output = Result<u64, i32>>
563                        + ::core::marker::Send
564                        + 'async_trait,
565                >,
566            >
567            where
568                'life0: 'async_trait,
569                Self: 'async_trait;
570        }
571
572    };
573    let result = impl_macro(input, true, false).unwrap();
574    let expected = quote! {
575        pub trait SampleTrait: 'static + Send + Sync {
576            #[must_use]
577            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
578            fn call<'life0, 'async_trait>(
579                &'life0 self,
580                p1: u64,
581                p2: u32,
582            ) -> ::core::pin::Pin<
583                Box<
584                    dyn ::core::future::Future<Output = Result<u64, i32> >
585                        + ::core::marker::Send
586                        + 'async_trait,
587                >,
588            >
589            where
590                'life0: 'async_trait,
591                Self: 'async_trait;
592        }
593
594        impl<______F___, ______Fut___> SampleTrait for ______F___
595            where
596                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(u64, u32) -> ______Fut___,
597                ______Fut___: ::core::future::Future<Output=Result<u64, i32> > + ::core::marker::Send + 'static
598        {
599            #[must_use]
600            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
601            fn call<'life0, 'async_trait>(
602                &'life0 self,
603                p1: u64,
604                p2: u32,
605            ) -> ::core::pin::Pin<
606                Box<
607                    dyn ::core::future::Future<Output = Result<u64, i32> >
608                        + ::core::marker::Send
609                        + 'async_trait,
610                >,
611            >
612            where
613                'life0: 'async_trait,
614                Self: 'async_trait {
615            Box::pin(async move {
616                let fut = (self)(p1, p2);
617                fut.await
618            })
619        }
620        }
621    };
622    assert_eq!(result.to_string(), expected.to_string());
623}
624
625#[test]
626fn test_impl_macro4() {
627    let input = syn::parse_quote! {
628        pub trait SampleTrait: 'static + Send + Sync {
629            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
630        }
631    };
632    let result = impl_macro(input, true,false).unwrap();
633    let expected = quote! {
634        pub trait SampleTrait: 'static + Send + Sync {
635            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
636        }
637        impl<______F___> SampleTrait for ______F___
638            where
639                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&u32, i16) -> Result<(), u32>
640        {
641            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
642                (self)(p1, p2)
643            }
644        }
645    };
646    assert_eq!(result.to_string(), expected.to_string());
647}
648
649#[test]
650fn test_impl_macro5() {
651    let input: ItemTrait = syn::parse_quote! {
652        pub trait SampleTrait: 'static + Send + Sync {
653            fn call(&self, p1: &u32, p2: i16);
654        }
655    };
656    let result = impl_macro(input, true, false).unwrap();
657    let expected = quote! {
658        pub trait SampleTrait: 'static + Send + Sync {
659            fn call(&self, p1: &u32, p2: i16);
660        }
661        impl<______F___> SampleTrait for ______F___
662            where
663                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&u32, i16)
664        {
665            fn call(&self, p1: &u32, p2: i16) {
666                (self)(p1, p2)
667            }
668        }
669    };
670    assert_eq!(result.to_string(), expected.to_string());
671}
672
673#[test]
674fn test_impl_macro6() {
675    let input: ItemTrait = syn::parse_quote! {
676        pub trait SampleTrait: 'static + Send + Sync {
677            async fn call(&self, p1: &u32, p2: i16);
678        }
679    };
680    let result = impl_macro(input, true, false).unwrap();
681    let expected = quote! {
682        #[async_trait::async_trait]
683        pub trait SampleTrait: 'static + Send + Sync {
684            async fn call(&self, p1: &u32, p2: i16);
685        }
686        #[async_trait::async_trait]
687        impl<______F___,______Fut___> SampleTrait for ______F___
688            where
689                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&u32, i16) -> ______Fut___,
690                ______Fut___: core::future::Future<Output=() > + 'static + core::marker::Send
691        {
692            async fn call(&self, p1: &u32, p2: i16) {
693                let fut = (self)(p1, p2);
694                fut.await
695            }
696        }
697    };
698    assert_eq!(result.to_string(), expected.to_string());
699}
700
701#[test]
702fn test_impl_macro7() {
703    let input = syn::parse_quote! {
704        pub trait SampleTrait: 'static + Send + Sync {
705            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
706        }
707    };
708    let result = impl_macro(input, false, false).unwrap();
709    let expected = quote! {
710        #[async_trait::async_trait]
711        pub trait SampleTrait: 'static + Send + Sync {
712            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
713        }
714        #[async_trait::async_trait]
715        impl<______F___, ______Fut___> SampleTrait for ______F___
716            where
717                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&'static u32, i16) -> ______Fut___,
718                ______Fut___: core::future::Future<Output=Result<(), u32> > + 'static + core::marker::Send
719        {
720            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
721                let p1: &'static u32 = unsafe {::core::mem::transmute(p1)};
722                let fut = (self)(p1, p2);
723                fut.await
724            }
725        }
726    };
727    assert_eq!(result.to_string(), expected.to_string());
728}
729
730#[test]
731fn test_impl_macro8() {
732    let input = syn::parse_quote! {
733        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
734            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
735        }
736    };
737    let result = impl_macro(input, false, false).unwrap();
738    let expected = quote! {
739        #[async_trait::async_trait]
740        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
741            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
742        }
743        #[async_trait::async_trait]
744        impl<T, ______F___, ______Fut___> SampleTrait<T> for ______F___
745            where
746                T: Send,
747                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(u256, u32, T) -> ______Fut___,
748                ______Fut___: core::future::Future<Output=Result<u64, Error> > + 'static + core::marker::Send
749        {
750            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error> {
751                let fut = (self)(p1, p2, t);
752                fut.await
753            }
754        }
755    };
756    assert_eq!(result.to_string(), expected.to_string());
757}
758
759#[test]
760fn test_impl_macro9() {
761    let input = syn::parse_quote! {
762        pub trait SampleTrait: 'static + Send + Sync {
763            #[must_use]
764            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
765            fn call<'life0, 'async_trait>(
766                &'life0 self,
767                p1: u64,
768                p2: u32,
769            ) -> ::core::pin::Pin<
770                Box<
771                    dyn ::core::future::Future<Output = Result<u64, i32>>
772                        + ::core::marker::Send
773                        + 'async_trait,
774                >,
775            >
776            where
777                'life0: 'async_trait,
778                Self: 'async_trait;
779        }
780
781    };
782    let result = impl_macro(input, false, false).unwrap();
783    let expected = quote! {
784        pub trait SampleTrait: 'static + Send + Sync {
785            #[must_use]
786            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
787            fn call<'life0, 'async_trait>(
788                &'life0 self,
789                p1: u64,
790                p2: u32,
791            ) -> ::core::pin::Pin<
792                Box<
793                    dyn ::core::future::Future<Output = Result<u64, i32> >
794                        + ::core::marker::Send
795                        + 'async_trait,
796                >,
797            >
798            where
799                'life0: 'async_trait,
800                Self: 'async_trait;
801        }
802
803        impl<______F___, ______Fut___> SampleTrait for ______F___
804            where
805                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(u64, u32) -> ______Fut___,
806                ______Fut___: ::core::future::Future<Output=Result<u64, i32> > + ::core::marker::Send + 'static
807        {
808            #[must_use]
809            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
810            fn call<'life0, 'async_trait>(
811                &'life0 self,
812                p1: u64,
813                p2: u32,
814            ) -> ::core::pin::Pin<
815                Box<
816                    dyn ::core::future::Future<Output = Result<u64, i32> >
817                        + ::core::marker::Send
818                        + 'async_trait,
819                >,
820            >
821            where
822                'life0: 'async_trait,
823                Self: 'async_trait {
824            Box::pin(async move {
825                let fut = (self)(p1, p2);
826                fut.await
827            })
828        }
829        }
830    };
831    assert_eq!(result.to_string(), expected.to_string());
832}
833
834#[test]
835fn test_impl_macro10() {
836    let input = syn::parse_quote! {
837        pub trait SampleTrait: 'static + Send + Sync {
838            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
839        }
840    };
841    let result = impl_macro(input, false, false).unwrap();
842    let expected = quote! {
843        pub trait SampleTrait: 'static + Send + Sync {
844            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
845        }
846        impl<______F___> SampleTrait for ______F___
847            where
848                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&'static u32, i16) -> Result<(), u32>
849        {
850            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
851                (self)(p1, p2)
852            }
853        }
854    };
855    assert_eq!(result.to_string(), expected.to_string());
856}
857
858#[test]
859fn test_impl_macro11() {
860    let input: ItemTrait = syn::parse_quote! {
861        pub trait SampleTrait: 'static + Send + Sync {
862            fn call(&self, p1: &u32, p2: i16);
863        }
864    };
865    let result = impl_macro(input, false, false).unwrap();
866    let expected = quote! {
867        pub trait SampleTrait: 'static + Send + Sync {
868            fn call(&self, p1: &u32, p2: i16);
869        }
870        impl<______F___> SampleTrait for ______F___
871            where
872                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&'static u32, i16)
873        {
874            fn call(&self, p1: &u32, p2: i16) {
875                (self)(p1, p2)
876            }
877        }
878    };
879    assert_eq!(result.to_string(), expected.to_string());
880}
881
882#[test]
883fn test_impl_macro12() {
884    let input: ItemTrait = syn::parse_quote! {
885        pub trait SampleTrait: 'static + Send + Sync {
886            async fn call(&self, p1: &u32, p2: i16);
887        }
888    };
889    let result = impl_macro(input, false, false).unwrap();
890    let expected = quote! {
891        #[async_trait::async_trait]
892        pub trait SampleTrait: 'static + Send + Sync {
893            async fn call(&self, p1: &u32, p2: i16);
894        }
895        #[async_trait::async_trait]
896        impl<______F___,______Fut___> SampleTrait for ______F___
897            where
898                ______F___: core::marker::Send + core::marker::Sync + 'static + Fn(&'static u32, i16) -> ______Fut___,
899                ______Fut___: core::future::Future<Output=() > + 'static + core::marker::Send
900        {
901            async fn call(&self, p1: &u32, p2: i16) {
902                let p1: &'static u32 = unsafe {::core::mem::transmute(p1)};
903                let fut = (self)(p1, p2);
904                fut.await
905            }
906        }
907    };
908    assert_eq!(result.to_string(), expected.to_string());
909}
910
911#[test]
912fn test_impl_macro13() {
913    let input = syn::parse_quote! {
914        pub trait SampleTrait {
915            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
916        }
917    };
918    let result = impl_macro(input, true, true).unwrap();
919    let expected = quote! {
920        #[async_trait::async_trait(?Send)]
921        pub trait SampleTrait {
922            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
923        }
924        #[async_trait::async_trait(?Send)]
925        impl<______F___, ______Fut___> SampleTrait for ______F___
926            where
927                ______F___: Fn(&u32, i16) -> ______Fut___,
928                ______Fut___: core::future::Future<Output=Result<(), u32> >
929        {
930            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
931                let fut = (self)(p1, p2);
932                fut.await
933            }
934        }
935    };
936    assert_eq!(result.to_string(), expected.to_string());
937}
938
939#[test]
940fn test_impl_macro14() {
941    let input = syn::parse_quote! {
942        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
943            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
944        }
945    };
946    let result = impl_macro(input, true, true).unwrap();
947    let expected = quote! {
948        #[async_trait::async_trait(?Send)]
949        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
950            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
951        }
952        #[async_trait::async_trait(?Send)]
953        impl<T, ______F___, ______Fut___> SampleTrait<T> for ______F___
954            where
955                T: Send,
956                ______F___: Fn(u256, u32, T) -> ______Fut___,
957                ______Fut___: core::future::Future<Output=Result<u64, Error> >
958        {
959            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error> {
960                let fut = (self)(p1, p2, t);
961                fut.await
962            }
963        }
964    };
965    assert_eq!(result.to_string(), expected.to_string());
966}
967
968#[test]
969fn test_impl_macro15() {
970    let input = syn::parse_quote! {
971        pub trait SampleTrait: 'static + Send + Sync {
972            #[must_use]
973            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
974            fn call<'life0, 'async_trait>(
975                &'life0 self,
976                p1: u64,
977                p2: u32,
978            ) -> ::core::pin::Pin<
979                Box<
980                    dyn ::core::future::Future<Output = Result<u64, i32>>
981                        + 'async_trait,
982                >,
983            >
984            where
985                'life0: 'async_trait,
986                Self: 'async_trait;
987        }
988
989    };
990    let result = impl_macro(input, true, true).unwrap();
991    let expected = quote! {
992        pub trait SampleTrait: 'static + Send + Sync {
993            #[must_use]
994            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
995            fn call<'life0, 'async_trait>(
996                &'life0 self,
997                p1: u64,
998                p2: u32,
999            ) -> ::core::pin::Pin<
1000                Box<
1001                    dyn ::core::future::Future<Output = Result<u64, i32> >
1002                        + 'async_trait,
1003                >,
1004            >
1005            where
1006                'life0: 'async_trait,
1007                Self: 'async_trait;
1008        }
1009
1010        impl<______F___, ______Fut___> SampleTrait for ______F___
1011            where
1012                ______F___: Fn(u64, u32) -> ______Fut___,
1013                ______Fut___: ::core::future::Future<Output=Result<u64, i32> >
1014        {
1015            #[must_use]
1016            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
1017            fn call<'life0, 'async_trait>(
1018                &'life0 self,
1019                p1: u64,
1020                p2: u32,
1021            ) -> ::core::pin::Pin<
1022                Box<
1023                    dyn ::core::future::Future<Output = Result<u64, i32> >
1024                        + 'async_trait,
1025                >,
1026            >
1027            where
1028                'life0: 'async_trait,
1029                Self: 'async_trait {
1030            Box::pin(async move {
1031                let fut = (self)(p1, p2);
1032                fut.await
1033            })
1034        }
1035        }
1036    };
1037    assert_eq!(result.to_string(), expected.to_string());
1038}
1039
1040#[test]
1041fn test_impl_macro16() {
1042    let input = syn::parse_quote! {
1043        pub trait SampleTrait: 'static + Send + Sync {
1044            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
1045        }
1046    };
1047    let result = impl_macro(input, true,true).unwrap();
1048    let expected = quote! {
1049        pub trait SampleTrait: 'static + Send + Sync {
1050            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
1051        }
1052        impl<______F___> SampleTrait for ______F___
1053            where
1054                ______F___: Fn(&u32, i16) -> Result<(), u32>
1055        {
1056            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
1057                (self)(p1, p2)
1058            }
1059        }
1060    };
1061    assert_eq!(result.to_string(), expected.to_string());
1062}
1063
1064#[test]
1065fn test_impl_macro17() {
1066    let input: ItemTrait = syn::parse_quote! {
1067        pub trait SampleTrait: 'static + Send + Sync {
1068            fn call(&self, p1: &u32, p2: i16);
1069        }
1070    };
1071    let result = impl_macro(input, true, true).unwrap();
1072    let expected = quote! {
1073        pub trait SampleTrait: 'static + Send + Sync {
1074            fn call(&self, p1: &u32, p2: i16);
1075        }
1076        impl<______F___> SampleTrait for ______F___
1077            where
1078                ______F___: Fn(&u32, i16)
1079        {
1080            fn call(&self, p1: &u32, p2: i16) {
1081                (self)(p1, p2)
1082            }
1083        }
1084    };
1085    assert_eq!(result.to_string(), expected.to_string());
1086}
1087
1088#[test]
1089fn test_impl_macro18() {
1090    let input: ItemTrait = syn::parse_quote! {
1091        pub trait SampleTrait: 'static + Send + Sync {
1092            async fn call(&self, p1: &u32, p2: i16);
1093        }
1094    };
1095    let result = impl_macro(input, true, true).unwrap();
1096    let expected = quote! {
1097        #[async_trait::async_trait(?Send)]
1098        pub trait SampleTrait: 'static + Send + Sync {
1099            async fn call(&self, p1: &u32, p2: i16);
1100        }
1101        #[async_trait::async_trait(?Send)]
1102        impl<______F___,______Fut___> SampleTrait for ______F___
1103            where
1104                ______F___: Fn(&u32, i16) -> ______Fut___,
1105                ______Fut___: core::future::Future<Output=() >
1106        {
1107            async fn call(&self, p1: &u32, p2: i16) {
1108                let fut = (self)(p1, p2);
1109                fut.await
1110            }
1111        }
1112    };
1113    assert_eq!(result.to_string(), expected.to_string());
1114}
1115
1116#[test]
1117fn test_impl_macro19() {
1118    let input = syn::parse_quote! {
1119        pub trait SampleTrait: 'static + Send + Sync {
1120            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
1121        }
1122    };
1123    let result = impl_macro(input, false, true).unwrap();
1124    let expected = quote! {
1125        #[async_trait::async_trait(?Send)]
1126        pub trait SampleTrait: 'static + Send + Sync {
1127            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
1128        }
1129        #[async_trait::async_trait(?Send)]
1130        impl<______F___, ______Fut___> SampleTrait for ______F___
1131            where
1132                ______F___: Fn(&'static u32, i16) -> ______Fut___,
1133                ______Fut___: core::future::Future<Output=Result<(), u32> >
1134        {
1135            async fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
1136                let p1: &'static u32 = unsafe {::core::mem::transmute(p1)};
1137                let fut = (self)(p1, p2);
1138                fut.await
1139            }
1140        }
1141    };
1142    assert_eq!(result.to_string(), expected.to_string());
1143}
1144
1145#[test]
1146fn test_impl_macro20() {
1147    let input = syn::parse_quote! {
1148        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
1149            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
1150        }
1151    };
1152    let result = impl_macro(input, false, true).unwrap();
1153    let expected = quote! {
1154        #[async_trait::async_trait(?Send)]
1155        pub trait SampleTrait<T>: 'static + Send + Sync where T: Send {
1156            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error>;
1157        }
1158        #[async_trait::async_trait(?Send)]
1159        impl<T, ______F___, ______Fut___> SampleTrait<T> for ______F___
1160            where
1161                T: Send,
1162                ______F___: Fn(u256, u32, T) -> ______Fut___,
1163                ______Fut___: core::future::Future<Output=Result<u64, Error> >
1164        {
1165            async fn call(&self, p1: u256, p2: u32, t: T) -> Result<u64, Error> {
1166                let fut = (self)(p1, p2, t);
1167                fut.await
1168            }
1169        }
1170    };
1171    assert_eq!(result.to_string(), expected.to_string());
1172}
1173
1174#[test]
1175fn test_impl_macro21() {
1176    let input = syn::parse_quote! {
1177        pub trait SampleTrait: 'static + Send + Sync {
1178            #[must_use]
1179            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
1180            fn call<'life0, 'async_trait>(
1181                &'life0 self,
1182                p1: u64,
1183                p2: u32,
1184            ) -> ::core::pin::Pin<
1185                Box<
1186                    dyn ::core::future::Future<Output = Result<u64, i32>>
1187                        + 'async_trait,
1188                >,
1189            >
1190            where
1191                'life0: 'async_trait,
1192                Self: 'async_trait;
1193        }
1194
1195    };
1196    let result = impl_macro(input, false, true).unwrap();
1197    let expected = quote! {
1198        pub trait SampleTrait: 'static + Send + Sync {
1199            #[must_use]
1200            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
1201            fn call<'life0, 'async_trait>(
1202                &'life0 self,
1203                p1: u64,
1204                p2: u32,
1205            ) -> ::core::pin::Pin<
1206                Box<
1207                    dyn ::core::future::Future<Output = Result<u64, i32> >
1208                        + 'async_trait,
1209                >,
1210            >
1211            where
1212                'life0: 'async_trait,
1213                Self: 'async_trait;
1214        }
1215
1216        impl<______F___, ______Fut___> SampleTrait for ______F___
1217            where
1218                ______F___: Fn(u64, u32) -> ______Fut___,
1219                ______Fut___: ::core::future::Future<Output=Result<u64, i32> >
1220        {
1221            #[must_use]
1222            #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
1223            fn call<'life0, 'async_trait>(
1224                &'life0 self,
1225                p1: u64,
1226                p2: u32,
1227            ) -> ::core::pin::Pin<
1228                Box<
1229                    dyn ::core::future::Future<Output = Result<u64, i32> >
1230                        + 'async_trait,
1231                >,
1232            >
1233            where
1234                'life0: 'async_trait,
1235                Self: 'async_trait {
1236            Box::pin(async move {
1237                let fut = (self)(p1, p2);
1238                fut.await
1239            })
1240        }
1241        }
1242    };
1243    assert_eq!(result.to_string(), expected.to_string());
1244}
1245
1246#[test]
1247fn test_impl_macro22() {
1248    let input = syn::parse_quote! {
1249        pub trait SampleTrait: 'static + Send + Sync {
1250            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
1251        }
1252    };
1253    let result = impl_macro(input, false, true).unwrap();
1254    let expected = quote! {
1255        pub trait SampleTrait: 'static + Send + Sync {
1256            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32>;
1257        }
1258        impl<______F___> SampleTrait for ______F___
1259            where
1260                ______F___: Fn(&'static u32, i16) -> Result<(), u32>
1261        {
1262            fn call(&self, p1: &u32, p2: i16) -> Result<(), u32> {
1263                (self)(p1, p2)
1264            }
1265        }
1266    };
1267    assert_eq!(result.to_string(), expected.to_string());
1268}
1269
1270#[test]
1271fn test_impl_macro23() {
1272    let input: ItemTrait = syn::parse_quote! {
1273        pub trait SampleTrait: 'static + Send + Sync {
1274            fn call(&self, p1: &u32, p2: i16);
1275        }
1276    };
1277    let result = impl_macro(input, false, true).unwrap();
1278    let expected = quote! {
1279        pub trait SampleTrait: 'static + Send + Sync {
1280            fn call(&self, p1: &u32, p2: i16);
1281        }
1282        impl<______F___> SampleTrait for ______F___
1283            where
1284                ______F___: Fn(&'static u32, i16)
1285        {
1286            fn call(&self, p1: &u32, p2: i16) {
1287                (self)(p1, p2)
1288            }
1289        }
1290    };
1291    assert_eq!(result.to_string(), expected.to_string());
1292}
1293
1294#[test]
1295fn test_impl_macro24() {
1296    let input: ItemTrait = syn::parse_quote! {
1297        pub trait SampleTrait: 'static + Send + Sync {
1298            async fn call(&self, p1: &u32, p2: i16);
1299        }
1300    };
1301    let result = impl_macro(input, false, true).unwrap();
1302    let expected = quote! {
1303        #[async_trait::async_trait(?Send)]
1304        pub trait SampleTrait: 'static + Send + Sync {
1305            async fn call(&self, p1: &u32, p2: i16);
1306        }
1307        #[async_trait::async_trait(?Send)]
1308        impl<______F___,______Fut___> SampleTrait for ______F___
1309            where
1310                ______F___: Fn(&'static u32, i16) -> ______Fut___,
1311                ______Fut___: core::future::Future<Output=() >
1312        {
1313            async fn call(&self, p1: &u32, p2: i16) {
1314                let p1: &'static u32 = unsafe {::core::mem::transmute(p1)};
1315                let fut = (self)(p1, p2);
1316                fut.await
1317            }
1318        }
1319    };
1320    assert_eq!(result.to_string(), expected.to_string());
1321}