@@ -44,6 +44,9 @@ struct Options {
44
44
45
45
#[ darling( default = "Options::default_async_local" ) ]
46
46
async_local : bool ,
47
+
48
+ #[ darling( default = "Options::default_generic" ) ]
49
+ generic : bool ,
47
50
}
48
51
49
52
impl Options {
@@ -54,6 +57,16 @@ impl Options {
54
57
fn default_async_local ( ) -> bool {
55
58
false
56
59
}
60
+
61
+ #[ cfg( feature = "generic-telemetry-wrapper" ) ]
62
+ fn default_generic ( ) -> bool {
63
+ true
64
+ }
65
+
66
+ #[ cfg( not( feature = "generic-telemetry-wrapper" ) ) ]
67
+ fn default_generic ( ) -> bool {
68
+ false
69
+ }
57
70
}
58
71
59
72
struct Args {
@@ -176,6 +189,8 @@ fn try_async_trait_fn_rewrite(args: &Args, body: &Block) -> Option<TokenStream2>
176
189
fn wrap_with_span ( args : & Args , block : TokenStream2 ) -> TokenStream2 {
177
190
let apply_fn = if args. options . async_local {
178
191
quote ! ( apply_local)
192
+ } else if args. options . generic {
193
+ quote ! ( apply_generic)
179
194
} else {
180
195
quote ! ( apply)
181
196
} ;
@@ -321,6 +336,38 @@ mod tests {
321
336
assert_eq ! ( actual, expected) ;
322
337
}
323
338
339
+ #[ test]
340
+ fn expand_async_fn_generic ( ) {
341
+ let args = parse_attr ! {
342
+ #[ span_fn( "async_span" , generic = true ) ]
343
+ } ;
344
+
345
+ let item_fn = parse_quote ! {
346
+ async fn do_async( ) -> io:: Result <String > {
347
+ do_something_else( ) . await ;
348
+
349
+ Ok ( "foo" . into( ) )
350
+ }
351
+ } ;
352
+
353
+ let actual = expand_from_parsed ( args, item_fn) . to_string ( ) ;
354
+
355
+ let expected = code_str ! {
356
+ async fn do_async<>( ) -> io:: Result <String > {
357
+ :: foundations:: telemetry:: tracing:: span( "async_span" )
358
+ . into_context( )
359
+ . apply_generic( async move { {
360
+ do_something_else( ) . await ;
361
+
362
+ Ok ( "foo" . into( ) )
363
+ } } )
364
+ . await
365
+ }
366
+ } ;
367
+
368
+ assert_eq ! ( actual, expected) ;
369
+ }
370
+
324
371
#[ test]
325
372
fn expand_async_trait_fn ( ) {
326
373
let args = parse_attr ! {
@@ -453,6 +500,72 @@ mod tests {
453
500
assert_eq ! ( actual, expected) ;
454
501
}
455
502
503
+ #[ test]
504
+ fn expand_async_trait_fn_generic ( ) {
505
+ let args = parse_attr ! {
506
+ #[ span_fn( "async_trait_span" , generic = true ) ]
507
+ } ;
508
+
509
+ let item_fn = parse_quote ! {
510
+ fn test<' life0, ' async_trait>(
511
+ & ' life0 self ,
512
+ ) -> :: core:: pin:: Pin <
513
+ Box <dyn :: core:: future:: Future <Output = String > + :: core:: marker:: Send + ' async_trait>
514
+ >
515
+ where
516
+ ' life0: ' async_trait,
517
+ Self : ' async_trait,
518
+ {
519
+ Box :: pin( async move {
520
+ if let :: core:: option:: Option :: Some ( __ret) = :: core:: option:: Option :: None :: <String > {
521
+ return __ret;
522
+ }
523
+ let __self = self ;
524
+ let __ret: String = {
525
+ __self. do_something_else( ) . await ;
526
+ "foo" . into( )
527
+ } ;
528
+ #[ allow( unreachable_code) ]
529
+ __ret
530
+ } )
531
+ }
532
+ } ;
533
+
534
+ let actual = expand_from_parsed ( args, item_fn) . to_string ( ) ;
535
+
536
+ let expected = code_str ! {
537
+ fn test<' life0, ' async_trait>(
538
+ & ' life0 self ,
539
+ ) -> :: core:: pin:: Pin <
540
+ Box <dyn :: core:: future:: Future <Output = String > + :: core:: marker:: Send + ' async_trait>
541
+ >
542
+ where
543
+ ' life0: ' async_trait,
544
+ Self : ' async_trait,
545
+ {
546
+ Box :: pin( async move {
547
+ :: foundations:: telemetry:: tracing:: span( "async_trait_span" )
548
+ . into_context( )
549
+ . apply_generic( async move {
550
+ if let :: core:: option:: Option :: Some ( __ret) = :: core:: option:: Option :: None :: <String > {
551
+ return __ret;
552
+ }
553
+ let __self = self ;
554
+ let __ret: String = {
555
+ __self. do_something_else( ) . await ;
556
+ "foo" . into( )
557
+ } ;
558
+ #[ allow( unreachable_code) ]
559
+ __ret
560
+ } )
561
+ . await
562
+ } )
563
+ }
564
+ } ;
565
+
566
+ assert_eq ! ( actual, expected) ;
567
+ }
568
+
456
569
#[ test]
457
570
fn expand_structure_with_crate_path ( ) {
458
571
let args = parse_attr ! {
0 commit comments