@@ -321,81 +321,82 @@ struct ModuleInfo {
321321impl ModuleInfo {
322322 fn parse ( it : & mut token_stream:: IntoIter ) -> Self {
323323 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 ] = & [ "type" , "name" , "license" ] ;
336+ let mut seen_keys = Vec :: new ( ) ;
326337
327338 loop {
328- let name = match it. next ( ) {
339+ let key = match it. next ( ) {
329340 Some ( TokenTree :: Ident ( ident) ) => ident. to_string ( ) ,
330341 Some ( _) => panic ! ( "Expected Ident or end" ) ,
331342 None => break ,
332343 } ;
333344
345+ if seen_keys. contains ( & key) {
346+ panic ! (
347+ "Duplicated key \" {}\" . Keys can only be specified once." ,
348+ key
349+ ) ;
350+ }
351+
334352 assert_eq ! ( expect_punct( it) , ':' ) ;
335353
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) ,
354+ match key. as_str ( ) {
355+ "type" => info. type_ = expect_ident ( it) ,
356+ "name" => info. name = expect_byte_string ( it) ,
357+ "author" => info. author = Some ( expect_byte_string ( it) ) ,
358+ "description" => info. description = Some ( expect_byte_string ( it) ) ,
359+ "license" => info. license = expect_byte_string ( it) ,
360+ "alias" => info. alias = Some ( expect_byte_string ( it) ) ,
361+ "alias_rtnl_link" => {
362+ info. alias = Some ( format ! ( "rtnl-link-{}" , expect_byte_string( it) ) )
373363 }
364+ "params" => info. params = Some ( expect_group ( it) ) ,
365+ _ => panic ! (
366+ "Unknown key \" {}\" . Valid keys are: {:?}." ,
367+ key, EXPECTED_KEYS
368+ ) ,
374369 }
370+
375371 assert_eq ! ( expect_punct( it) , ',' ) ;
372+
373+ seen_keys. push ( key) ;
376374 }
377375
378376 expect_end ( it) ;
379377
380- if info. type_ . is_empty ( ) {
381- panic ! ( "'type' not specified in module macro" ) ;
378+ for key in REQUIRED_KEYS {
379+ if !seen_keys. iter ( ) . any ( |e| e == key) {
380+ panic ! ( "Missing required key \" {}\" ." , key) ;
381+ }
382382 }
383- if info. license . is_empty ( ) {
384- panic ! ( "'license' not specified in module macro" ) ;
383+
384+ let mut ordered_keys: Vec < & str > = Vec :: new ( ) ;
385+ for key in EXPECTED_KEYS {
386+ if seen_keys. iter ( ) . any ( |e| e == key) {
387+ ordered_keys. push ( key) ;
388+ }
385389 }
386- if info. name . is_empty ( ) {
387- panic ! ( "'name' not specified in module macro" ) ;
390+
391+ if seen_keys != ordered_keys {
392+ panic ! (
393+ "Keys are not ordered as expected. Order them like: {:?}." ,
394+ ordered_keys
395+ ) ;
388396 }
389397
390398 info
391399 }
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- }
399400}
400401
401402/// Declares a kernel module.
0 commit comments