@@ -14,22 +14,58 @@ macro_rules! _main_parse {
1414}
1515
1616#[ macro_export]
17- macro_rules! _parse_ignore {
18- ( ignore) => {
19- :: std:: option:: Option :: <& ' static str >:: None
17+ #[ allow( clippy:: crate_in_macro_def) ] // accessing item defined by `_main_parse`/`_parse_ignore`, and recursively calling the macro itself
18+ macro_rules! _test_parse {
19+ // Entry point
20+ ( #[ test] $( #[ $( $attr: tt) +] ) * fn $name: ident $( $item: tt) * ) => {
21+ $crate:: _private:: test_parse!( continue :
22+ name=$name
23+ body=[ $( $item) * ]
24+ attrs=[ $( #[ $( $attr) +] ) * ]
25+ ) ;
26+ } ;
27+
28+ // Recursively handle attributes:
29+
30+ // Edge condition (no more attributes to parse)
31+ ( continue : name=$name: ident body=[ $( $item: tt) * ] attrs=[ ] $( ignore=$ignore: tt) ?) => {
32+ $crate:: _private:: test_parse!( break :
33+ name=$name
34+ body=[ $( $item) * ]
35+ $( ignore=$ignore) ?
36+ ) ;
2037 } ;
21- ( ignore = $reason: expr) => {
22- :: std:: option:: Option :: <& ' static str >:: Some ( $reason)
38+ // Process `#[ignore]`/`#[ignore = ".."]` (NOTE: This will only match if an ignore macro has not already been parsed)
39+ ( continue : name=$name: ident body=[ $( $item: tt) * ] attrs=[ #[ ignore $( = $reason: literal) ?] $( #[ $( $attr: tt) +] ) * ] ) => {
40+ $crate:: _private:: test_parse!( continue :
41+ name=$name
42+ body=[ $( $item) * ]
43+ attrs=[ $( #[ $( $attr) * ] ) * ]
44+ ignore=[ $( $reason) ?]
45+ ) ;
2346 } ;
24- ( $( $attr: tt) * ) => {
25- compile_error!( concat!( "unknown attribute '" , stringify!( $( $attr) * ) , "'" ) ) ;
47+ // Ignore subsequent calls to `#[ignore]`/`#[ignore = ".."]`
48+ ( continue : name=$name: ident body=[ $( $item: tt) * ] attrs=[ #[ ignore $( = $reason: literal) ?] $( #[ $( $attr: tt) +] ) * ] ignore=$ignore: tt) => {
49+ $crate:: _private:: test_parse!( continue :
50+ name=$name
51+ body=[ $( $item) * ]
52+ attrs=[ $( #[ $( $attr) * ] ) * ]
53+ ignore=$ignore
54+ ) ;
55+ } ;
56+ // Emit error on unknown attributes (but continue parsing)
57+ ( continue : name=$name: ident body=[ $( $item: tt) * ] attrs=[ #[ $( $unknown_attr: tt) +] $( #[ $( $attr: tt) +] ) * ] $( ignore=$ignore: tt) ?) => {
58+ compile_error!( concat!( "unknown attribute '" , stringify!( $( $unknown_attr) +) , "'" ) ) ;
59+ $crate:: _private:: test_parse!( continue :
60+ name=$name
61+ body=[ $( $item) * ]
62+ attrs=[ $( #[ $( $attr) * ] ) * ]
63+ $( ignore=$ignore) ?
64+ ) ;
2665 } ;
27- }
2866
29- #[ macro_export]
30- #[ allow( clippy:: crate_in_macro_def) ] // accessing item defined by `_main_parse`
31- macro_rules! _test_parse {
32- ( #[ test] $( #[ $( $attr: tt) * ] ) * fn $name: ident $( $item: tt) * ) => {
67+ // End result
68+ ( break : name=$name: ident body=[ $( $item: tt) * ] $( ignore=$ignore: tt) ?) => {
3369 #[ allow( non_camel_case_types) ]
3470 struct $name;
3571
@@ -52,12 +88,7 @@ macro_rules! _test_parse {
5288 fn run( & self , context: & $crate:: TestContext ) -> $crate:: RunResult {
5389 fn run $( $item) *
5490
55- $(
56- match $crate:: _private:: parse_ignore!( $( $attr) * ) {
57- :: std:: option:: Option :: None => context. ignore( ) ?,
58- :: std:: option:: Option :: Some ( reason) => context. ignore_for( reason) ?,
59- }
60- ) *
91+ $crate:: _private:: parse_ignore!( context, $( $ignore) ?) ;
6192
6293 use $crate:: IntoRunResult ;
6394 let result = run( context) ;
@@ -66,3 +97,14 @@ macro_rules! _test_parse {
6697 }
6798 } ;
6899}
100+
101+ #[ macro_export]
102+ macro_rules! _parse_ignore {
103+ ( $context: expr, [ $reason: literal] $( , ) ?) => {
104+ $context. ignore_for( $reason) ?
105+ } ;
106+ ( $context: expr, [ ] $( , ) ?) => {
107+ $context. ignore( ) ?
108+ } ;
109+ ( $context: expr $( , ) ?) => { } ;
110+ }
0 commit comments