@@ -22,30 +22,74 @@ impl Parse for AsyncItem {
22
22
23
23
pub struct RecursionArgs {
24
24
pub send_bound : bool ,
25
- }
26
-
27
- impl Default for RecursionArgs {
28
- fn default ( ) -> Self {
29
- RecursionArgs { send_bound : true }
30
- }
25
+ pub sync_bound : bool ,
31
26
}
32
27
33
28
/// Custom keywords for parser
34
29
mod kw {
35
30
syn:: custom_keyword!( Send ) ;
31
+ syn:: custom_keyword!( Sync ) ;
36
32
}
37
33
38
- impl Parse for RecursionArgs {
34
+ #[ derive( Debug , PartialEq , Eq ) ]
35
+ enum Arg {
36
+ NotSend ,
37
+ Sync ,
38
+ }
39
+
40
+ impl std:: fmt:: Display for Arg {
41
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
42
+ match self {
43
+ Self :: NotSend => write ! ( f, "?Send" ) ,
44
+ Self :: Sync => write ! ( f, "Sync" ) ,
45
+ }
46
+ }
47
+ }
48
+
49
+ impl Parse for Arg {
39
50
fn parse ( input : ParseStream ) -> Result < Self > {
40
- // Check for the `?Send` option
41
51
if input. peek ( Token ! [ ?] ) {
42
52
input. parse :: < Question > ( ) ?;
43
53
input. parse :: < kw:: Send > ( ) ?;
44
- Ok ( Self { send_bound : false } )
45
- } else if !input. is_empty ( ) {
46
- Err ( input. error ( "expected `?Send` or empty" ) )
54
+ Ok ( Arg :: NotSend )
47
55
} else {
48
- Ok ( Self :: default ( ) )
56
+ input. parse :: < kw:: Sync > ( ) ?;
57
+ Ok ( Arg :: Sync )
49
58
}
50
59
}
51
60
}
61
+
62
+ impl Parse for RecursionArgs {
63
+ fn parse ( input : ParseStream ) -> Result < Self > {
64
+ let mut send_bound: bool = true ;
65
+ let mut sync_bound: bool = false ;
66
+
67
+ let args_parsed: Vec < Arg > =
68
+ syn:: punctuated:: Punctuated :: < Arg , syn:: Token ![ , ] > :: parse_terminated ( input)
69
+ . map_err ( |e| input. error ( format ! ( "failed to parse macro arguments: {e}" ) ) ) ?
70
+ . into_iter ( )
71
+ . collect ( ) ;
72
+
73
+ // Avoid sloppy input
74
+ if args_parsed. len ( ) > 2 {
75
+ return Err ( Error :: new ( Span :: call_site ( ) , "received too many arguments" ) ) ;
76
+ } else if args_parsed. len ( ) == 2 && args_parsed[ 0 ] == args_parsed[ 1 ] {
77
+ return Err ( Error :: new (
78
+ Span :: call_site ( ) ,
79
+ format ! ( "received duplicate argument: `{}`" , args_parsed[ 0 ] ) ,
80
+ ) ) ;
81
+ }
82
+
83
+ for arg in args_parsed {
84
+ match arg {
85
+ Arg :: NotSend => send_bound = false ,
86
+ Arg :: Sync => sync_bound = true ,
87
+ }
88
+ }
89
+
90
+ Ok ( Self {
91
+ send_bound,
92
+ sync_bound,
93
+ } )
94
+ }
95
+ }
0 commit comments