@@ -204,21 +204,32 @@ impl Parse for FieldOrMethod {
204
204
}
205
205
206
206
/// Either field or method call matcher. E.g.:
207
- /// * `field: starts_with("something")`
207
+ /// * `field: starts_with("something")` or `field: _`
208
208
/// * `property(arg1, arg2): starts_with("something")
209
209
struct FieldOrMethodPattern {
210
210
ref_token : Option < Token ! [ ref] > ,
211
211
field_or_method : FieldOrMethod ,
212
- matcher : Expr ,
212
+ /// When `None`, it represents `_` which matches anything, meaning we should
213
+ /// ignore it.
214
+ matcher : Option < Expr > ,
213
215
}
214
216
215
217
impl Parse for FieldOrMethodPattern {
216
218
fn parse ( input : ParseStream ) -> syn:: Result < Self > {
217
- Ok ( FieldOrMethodPattern {
218
- field_or_method : input. parse ( ) ?,
219
- ref_token : input. parse ( ) ?,
220
- matcher : input. parse ( ) ?,
221
- } )
219
+ let field_or_method: FieldOrMethod = input. parse ( ) ?;
220
+ let underscore = input. parse :: < Option < Token ! [ _] > > ( ) ?;
221
+ match underscore {
222
+ Some ( underscore) if matches ! ( field_or_method, FieldOrMethod :: Method ( _) ) => compile_err (
223
+ underscore. spans [ 0 ] ,
224
+ "Don't match a method call against `_`. Just omit it instead." ,
225
+ ) ,
226
+ Some ( _) => Ok ( FieldOrMethodPattern { field_or_method, ref_token : None , matcher : None } ) ,
227
+ None => Ok ( FieldOrMethodPattern {
228
+ field_or_method,
229
+ ref_token : input. parse ( ) ?,
230
+ matcher : Some ( input. parse ( ) ?) ,
231
+ } ) ,
232
+ }
222
233
}
223
234
}
224
235
@@ -231,13 +242,17 @@ fn parse_braced_pattern_args(
231
242
let mut field_names = vec ! [ ] ;
232
243
let field_patterns: Vec < TokenStream > = patterns
233
244
. into_iter ( )
234
- . map ( |FieldOrMethodPattern { ref_token, field_or_method, matcher } | match field_or_method {
235
- FieldOrMethod :: Field ( ident) => {
236
- field_names. push ( ident. clone ( ) ) ;
237
- quote ! { field!( #struct_name . #ident, #ref_token #matcher) }
238
- }
239
- FieldOrMethod :: Method ( call) => {
240
- quote ! { property!( #struct_name . #call, #ref_token #matcher) }
245
+ . filter_map ( |FieldOrMethodPattern { ref_token, field_or_method, matcher } | {
246
+ match field_or_method {
247
+ FieldOrMethod :: Field ( ident) => {
248
+ field_names. push ( ident. clone ( ) ) ;
249
+ matcher. map ( |matcher| {
250
+ quote ! { field!( #struct_name . #ident, #ref_token #matcher) }
251
+ } )
252
+ }
253
+ FieldOrMethod :: Method ( call) => {
254
+ Some ( quote ! { property!( #struct_name . #call, #ref_token #matcher) } )
255
+ }
241
256
}
242
257
} )
243
258
. collect ( ) ;
0 commit comments