将属性应用于宏扩展

kpo*_*zin 3 rust

我正在使用宏来生成测试。想象一个像这样的简单定义:

macro_rules! my_test {
    ($name:ident) => {
       #[test]
       fn $name() {
         assert_eq!(6, 3 + 3);
       }
    };
}
Run Code Online (Sandbox Code Playgroud)

我想禁用我以这种方式生成的一些测试:

my_test!(good_test_a);

my_test!(good_test_b);

#[ignore]
my_test!(bad_test_a);

#[ignore]
my_test!(bad_test_b);
Run Code Online (Sandbox Code Playgroud)

但是,根据这个 GitHub 问题

应用于宏调用的属性在宏扩展期间被消除。

事实上,所有的测试都在运行;没有一个被忽略。(参见Rust Playground。)

是否有针对此限制的实际解决方法?是否有其他调用宏的方法可以将#[ignore]属性应用于其扩展?

Cen*_*ril 5

是否有针对此限制的实际解决方法?

是的。通过允许宏本身通过meta宏片段接受属性,您可以像这样解决问题:

#![cfg(test)]

macro_rules! my_test {
    ($(#[$m:meta])* // This accepts `#[foo] #[bar(..)] ..`
     $name:ident) => {
       $(#[$m])* // This expands the attributes.
       #[test]
       fn $name() {
         assert_eq!(6, 3 + 3);
       }
    };
}

my_test!(good_test_a);

my_test!(good_test_b);

// You can pass in `#[ignore]` or any series of attributes you wish:
my_test!(#[ignore] bad_test_a);

my_test!(#[ignore] bad_test_b);
Run Code Online (Sandbox Code Playgroud)

运行这个,我们得到:

running 4 tests
test bad_test_a ... ignored
test bad_test_b ... ignored
test good_test_a ... ok
test good_test_b ... ok

test result: ok. 2 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out
Run Code Online (Sandbox Code Playgroud)