Skip to main content

rstest_log_macros/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as Tokens;
3use quote::quote;
4use syn::{
5    parse_macro_input,
6    ItemFn,
7};
8
9
10#[proc_macro_attribute]
11pub fn rstest(attr: TokenStream, item: TokenStream) -> TokenStream {
12    // the "full" rstest syntax looks like
13    //
14    // #[rstest]
15    // #[case(...)]
16    // #[case(...)]
17    // #[tokio::test]
18    // async fn test_blah(#[case] ...)
19    //
20    // We want to support a similar usage for test_log, so with this library the syntax looks like
21    //
22    // #[rstest(tokio::test)]
23    // #[case(...)]
24    // #[case(...)]
25    // async fn test_blah(#[case] ...)
26    //
27    // This needs to be desugared into the following:
28    //
29    // #[rstest]
30    // #[case(...)]
31    // #[case(...)]
32    // #[test_log::test]
33    // #[tokio::test]
34
35    let ItemFn { attrs, vis, sig, block } = parse_macro_input!(item as ItemFn);
36    let internal_attr = if attr.is_empty() {
37        quote! {}
38    } else {
39        let attr_tokens: Tokens = attr.into();
40        quote! { #[ #attr_tokens ] }
41    };
42    quote! {
43        #[ ::test_log::test(::rstest::rstest) ]
44        #(#attrs)*
45        #internal_attr
46        #vis #sig #block
47    }
48    .into()
49}