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}