@@ -8,18 +8,21 @@ use syn::{
8
8
parse:: { Parse , ParseStream } ,
9
9
parse_macro_input,
10
10
spanned:: Spanned ,
11
- Error , Ident , LitStr , Pat , PatIdent , Result ,
11
+ Error , Expr , Ident , LitStr , Pat , PatIdent , Result , Token ,
12
12
} ;
13
13
14
14
struct MacroInput {
15
15
use_std : bool ,
16
16
pat : Pat ,
17
+ in_value : Expr ,
17
18
}
18
19
19
20
impl Parse for MacroInput {
20
21
fn parse ( input : ParseStream ) -> Result < Self > {
21
22
let std_mode: Ident = input. parse ( ) ?;
22
23
let pat = input. parse ( ) ?;
24
+ input. parse :: < Token ! [ =] > ( ) ?;
25
+ let in_value = input. parse ( ) ?;
23
26
24
27
Ok ( Self {
25
28
use_std : if std_mode == "std" {
@@ -30,79 +33,92 @@ impl Parse for MacroInput {
30
33
return Err ( Error :: new_spanned ( std_mode, "" ) ) ;
31
34
} ,
32
35
pat,
36
+ in_value,
33
37
} )
34
38
}
35
39
}
36
40
37
41
#[ proc_macro_hack:: proc_macro_hack]
38
42
#[ proc_macro_error:: proc_macro_error]
39
- pub fn collect_captures ( input : TokenStream ) -> TokenStream {
40
- let MacroInput { use_std, pat } = parse_macro_input ! ( input) ;
43
+ pub fn implicit_try_match_inner ( input : TokenStream ) -> TokenStream {
44
+ let MacroInput {
45
+ use_std,
46
+ pat,
47
+ in_value,
48
+ } = parse_macro_input ! ( input) ;
41
49
42
50
let mut idents = Vec :: new ( ) ;
43
51
collect_pat_ident ( & pat, & mut idents) ;
44
52
45
- // Check if bound variables are all like `_0`, `_1`, in which case
46
- // collect them in a tuple
47
- if let Some ( tokens) = check_tuple_captures ( & idents) {
48
- return tokens. into ( ) ;
49
- }
50
-
51
- // Decide what to do based on the number of bound variables
52
- let output = match & idents[ ..] {
53
- [ ] => {
54
- quote ! { ( ) }
55
- }
56
- [ single] => {
57
- quote ! { #single}
58
- }
59
- multi => {
60
- // `var1`, `var2`, ...
61
- let idents: Vec < _ > = multi. iter ( ) . map ( |p| p. ident . clone ( ) ) . collect ( ) ;
62
-
63
- // `_M_0`, `_M_1`, ...
64
- let ty_params: Vec < _ > = ( 0 ..idents. len ( ) )
65
- . map ( |i| Ident :: new ( & format ! ( "_M_{}" , i) , Span :: call_site ( ) ) )
66
- . collect ( ) ;
67
-
68
- // `"var1"`, `"var2"`, ...
69
- let ident_strs: Vec < _ > = idents
70
- . iter ( )
71
- . map ( |i| LitStr :: new ( & format ! ( "{}" , i) , i. span ( ) ) )
72
- . collect ( ) ;
73
-
74
- let ty_name = Ident :: new ( "__Match" , Span :: call_site ( ) ) ;
75
-
76
- let debug_impl = if use_std {
77
- let fmt = quote ! { :: std:: fmt } ;
78
- quote ! {
79
- impl <#( #ty_params) , * > #fmt:: Debug for #ty_name<#( #ty_params) , * >
80
- where
81
- #( #ty_params: #fmt:: Debug ) , *
82
- {
83
- fn fmt( & self , f: & mut #fmt:: Formatter <' _>) -> #fmt:: Result {
84
- f. debug_struct( "<anonymous>" )
85
- #( . field( #ident_strs, & self . #idents) ) *
86
- . finish( )
87
- }
88
- }
53
+ let success_output =
54
+ // Check if bound variables are all like `_0`, `_1`, in which case
55
+ // collect them in a tuple
56
+ if let Some ( tokens) = check_tuple_captures ( & idents) {
57
+ tokens
58
+ } else {
59
+ // Decide what to do based on the number of bound variables
60
+ match & idents[ ..] {
61
+ [ ] => {
62
+ quote ! { ( ) }
89
63
}
90
- } else {
91
- quote ! { }
92
- } ;
93
-
94
- quote ! { {
95
- #[ derive( Clone , Copy ) ]
96
- struct #ty_name<#( #ty_params) , * > {
97
- #(
98
- #idents: #ty_params
99
- ) , *
64
+ [ single] => {
65
+ quote ! { #single}
100
66
}
67
+ multi => {
68
+ // `var1`, `var2`, ...
69
+ let idents: Vec < _ > = multi. iter ( ) . map ( |p| p. ident . clone ( ) ) . collect ( ) ;
70
+
71
+ // `_M_0`, `_M_1`, ...
72
+ let ty_params: Vec < _ > = ( 0 ..idents. len ( ) )
73
+ . map ( |i| Ident :: new ( & format ! ( "_M_{}" , i) , Span :: call_site ( ) ) )
74
+ . collect ( ) ;
75
+
76
+ // `"var1"`, `"var2"`, ...
77
+ let ident_strs: Vec < _ > = idents
78
+ . iter ( )
79
+ . map ( |i| LitStr :: new ( & format ! ( "{}" , i) , i. span ( ) ) )
80
+ . collect ( ) ;
81
+
82
+ let ty_name = Ident :: new ( "__Match" , Span :: call_site ( ) ) ;
83
+
84
+ let debug_impl = if use_std {
85
+ let fmt = quote ! { :: std:: fmt } ;
86
+ quote ! {
87
+ impl <#( #ty_params) , * > #fmt:: Debug for #ty_name<#( #ty_params) , * >
88
+ where
89
+ #( #ty_params: #fmt:: Debug ) , *
90
+ {
91
+ fn fmt( & self , f: & mut #fmt:: Formatter <' _>) -> #fmt:: Result {
92
+ f. debug_struct( "<anonymous>" )
93
+ #( . field( #ident_strs, & self . #idents) ) *
94
+ . finish( )
95
+ }
96
+ }
97
+ }
98
+ } else {
99
+ quote ! { }
100
+ } ;
101
+
102
+ quote ! { {
103
+ #[ derive( Clone , Copy ) ]
104
+ struct #ty_name<#( #ty_params) , * > {
105
+ #(
106
+ #idents: #ty_params
107
+ ) , *
108
+ }
101
109
102
- #debug_impl
110
+ #debug_impl
111
+
112
+ #ty_name { #( #idents) , * }
113
+ } }
114
+ }
115
+ }
116
+ } ;
103
117
104
- #ty_name { #( #idents) , * }
105
- } }
118
+ let output = quote ! {
119
+ match #in_value {
120
+ #pat => :: core:: result:: Result :: Ok ( #success_output) ,
121
+ in_value => :: core:: result:: Result :: Err ( in_value) ,
106
122
}
107
123
} ;
108
124
0 commit comments