@@ -321,81 +321,75 @@ struct ModuleInfo {
321
321
impl ModuleInfo {
322
322
fn parse ( it : & mut token_stream:: IntoIter ) -> Self {
323
323
let mut info = ModuleInfo :: default ( ) ;
324
- // The first allowed position is 1, to prevent setting something twice.
325
- let mut pos = 0u8 ;
324
+
325
+ const EXPECTED_KEYS : & [ & str ] = & [
326
+ "type" ,
327
+ "name" ,
328
+ "author" ,
329
+ "description" ,
330
+ "license" ,
331
+ "alias" ,
332
+ "alias_rtnl_link" ,
333
+ "params"
334
+ ] ;
335
+ const REQUIRED_KEYS : & [ & str ] = & [
336
+ "type" ,
337
+ "name" ,
338
+ "license" ,
339
+ ] ;
340
+ let mut seen_keys = Vec :: new ( ) ;
326
341
327
342
loop {
328
- let name = match it. next ( ) {
343
+ let key = match it. next ( ) {
329
344
Some ( TokenTree :: Ident ( ident) ) => ident. to_string ( ) ,
330
345
Some ( _) => panic ! ( "Expected Ident or end" ) ,
331
346
None => break ,
332
347
} ;
333
348
349
+ if seen_keys. contains ( & key) {
350
+ panic ! ( "Duplicated key \" {}\" . Keys can only be specified once." , key) ;
351
+ }
352
+
334
353
assert_eq ! ( expect_punct( it) , ':' ) ;
335
354
336
- if name == "type" {
337
- Self :: allowed_pos ( & mut pos, 1 , & name) ;
338
- let type_ = expect_ident ( it) ;
339
- info. type_ = type_;
340
- } else if name == "params" {
341
- Self :: allowed_pos ( & mut pos, 7 , & name) ;
342
- let params = expect_group ( it) ;
343
- info. params = Some ( params) ;
344
- } else {
345
- let value = expect_byte_string ( it) ;
346
-
347
- match name. as_str ( ) {
348
- "name" => {
349
- Self :: allowed_pos ( & mut pos, 2 , & name) ;
350
- info. name = value;
351
- }
352
- "author" => {
353
- Self :: allowed_pos ( & mut pos, 3 , & name) ;
354
- info. author = Some ( value) ;
355
- }
356
- "description" => {
357
- Self :: allowed_pos ( & mut pos, 4 , & name) ;
358
- info. description = Some ( value) ;
359
- }
360
- "license" => {
361
- Self :: allowed_pos ( & mut pos, 5 , & name) ;
362
- info. license = value;
363
- }
364
- "alias" => {
365
- Self :: allowed_pos ( & mut pos, 6 , & name) ;
366
- info. alias = Some ( value) ;
367
- }
368
- "alias_rtnl_link" => {
369
- Self :: allowed_pos ( & mut pos, 6 , & name) ;
370
- info. alias = Some ( format ! ( "rtnl-link-{}" , value) ) ;
371
- }
372
- _ => panic ! ( "field '{}' is not supported by module" , name) ,
373
- }
355
+ match key. as_str ( ) {
356
+ "type" => info. type_ = expect_ident ( it) ,
357
+ "name" => info. name = expect_byte_string ( it) ,
358
+ "author" => info. author = Some ( expect_byte_string ( it) ) ,
359
+ "description" => info. description = Some ( expect_byte_string ( it) ) ,
360
+ "license" => info. license = expect_byte_string ( it) ,
361
+ "alias" => info. alias = Some ( expect_byte_string ( it) ) ,
362
+ "alias_rtnl_link" => info. alias = Some ( format ! ( "rtnl-link-{}" , expect_byte_string( it) ) ) ,
363
+ "params" => info. params = Some ( expect_group ( it) ) ,
364
+ _ => panic ! ( "Unknown key \" {}\" . Valid keys are: {:?}." , key, EXPECTED_KEYS ) ,
374
365
}
366
+
375
367
assert_eq ! ( expect_punct( it) , ',' ) ;
368
+
369
+ seen_keys. push ( key) ;
376
370
}
377
371
378
372
expect_end ( it) ;
379
373
380
- if info. type_ . is_empty ( ) {
381
- panic ! ( "'type' not specified in module macro" ) ;
374
+ for key in REQUIRED_KEYS {
375
+ if !seen_keys. iter ( ) . any ( |e| e == key) {
376
+ panic ! ( "Missing required key \" {}\" ." , key) ;
377
+ }
382
378
}
383
- if info. license . is_empty ( ) {
384
- panic ! ( "'license' not specified in module macro" ) ;
379
+
380
+ let mut ordered_keys: Vec < & str > = Vec :: new ( ) ;
381
+ for key in EXPECTED_KEYS {
382
+ if seen_keys. iter ( ) . any ( |e| e == key) {
383
+ ordered_keys. push ( key) ;
384
+ }
385
385
}
386
- if info. name . is_empty ( ) {
387
- panic ! ( "'name' not specified in module macro" ) ;
386
+
387
+ if seen_keys != ordered_keys {
388
+ panic ! ( "Keys are not ordered as expected. Order them like: {:?}." , ordered_keys) ;
388
389
}
389
390
390
391
info
391
392
}
392
-
393
- fn allowed_pos ( pos : & mut u8 , allowed_pos : u8 , name : & str ) {
394
- if * pos > allowed_pos {
395
- panic ! ( "'{}' is not allowed at this position" , name) ;
396
- }
397
- * pos = allowed_pos;
398
- }
399
393
}
400
394
401
395
/// Declares a kernel module.
0 commit comments