@@ -6,14 +6,15 @@ use std::ffi::OsString;
66use std:: path:: { Path , PathBuf } ;
77use syn:: parse:: { Parse , ParseStream } ;
88use syn:: punctuated:: Punctuated ;
9- use syn:: { bracketed, parse_macro_input, Expr , LitStr , Token } ;
9+ use syn:: { bracketed, parse_macro_input, Expr , LitStr , Meta , Token } ;
1010use unicode_ident:: { is_xid_continue, is_xid_start} ;
1111
1212struct TestEachArgs {
1313 path : LitStr ,
1414 module : Option < Ident > ,
1515 function : Expr ,
1616 extensions : Vec < String > ,
17+ attributes : Vec < Meta > ,
1718}
1819
1920macro_rules! abort {
@@ -30,6 +31,20 @@ macro_rules! abort_token_stream {
3031
3132impl Parse for TestEachArgs {
3233 fn parse ( input : ParseStream ) -> syn:: Result < Self > {
34+ // Optionally parse attributes if `#` is used. Aborts if none are given.
35+ let attributes = input
36+ . parse :: < Token ! [ #] > ( )
37+ . and_then ( |_| {
38+ let content;
39+ bracketed ! ( content in input) ;
40+
41+ match Punctuated :: < Meta , Token ! [ , ] > :: parse_separated_nonempty ( & content) {
42+ Ok ( attributes) => Ok ( attributes. into_iter ( ) . collect ( ) ) ,
43+ Err ( e) => abort ! ( e. span( ) , "Expected at least one attribute to be given." ) ,
44+ }
45+ } )
46+ . unwrap_or_default ( ) ;
47+
3348 // Optionally parse extensions if the keyword `for` is used. Aborts if none are given.
3449 let extensions = input
3550 . parse :: < Token ! [ for ] > ( )
@@ -81,6 +96,7 @@ impl Parse for TestEachArgs {
8196 module,
8297 function,
8398 extensions,
99+ attributes,
84100 } )
85101 }
86102}
@@ -226,6 +242,12 @@ fn generate_from_tree(
226242 quote ! ( [ #arguments] )
227243 } ;
228244
245+ for attribute in & parsed. attributes {
246+ stream. extend ( quote ! {
247+ #[ #attribute]
248+ } ) ;
249+ }
250+
229251 stream. extend ( quote ! {
230252 #[ test]
231253 fn #file_name( ) {
0 commit comments