facet_testhelpers_macros/
lib.rs

1use unsynn::*;
2
3keyword! {
4    KFn = "fn";
5}
6
7unsynn! {
8    struct UntilFn {
9        items: Any<Cons<Except<KFn>, TokenTree>>,
10    }
11
12    struct UntilBody {
13        items: Any<Cons<Except<BraceGroup>, TokenTree>>,
14    }
15
16    struct Body {
17        items: BraceGroup,
18    }
19
20    struct FunctionDecl {
21        until_fn: UntilFn, _fn: KFn, name: Ident,
22        until_body: UntilBody, body: Body
23    }
24}
25
26impl quote::ToTokens for UntilFn {
27    fn to_tokens(&self, tokens: &mut unsynn::TokenStream) {
28        self.items.to_tokens(tokens)
29    }
30}
31
32impl quote::ToTokens for UntilBody {
33    fn to_tokens(&self, tokens: &mut unsynn::TokenStream) {
34        self.items.to_tokens(tokens)
35    }
36}
37
38impl quote::ToTokens for Body {
39    fn to_tokens(&self, tokens: &mut unsynn::TokenStream) {
40        tokens.extend(self.items.0.stream())
41    }
42}
43
44#[proc_macro_attribute]
45pub fn test(
46    _attr: proc_macro::TokenStream,
47    item: proc_macro::TokenStream,
48) -> proc_macro::TokenStream {
49    let item = TokenStream::from(item);
50    let mut i = item.to_token_iter();
51    let fdecl = i.parse::<FunctionDecl>().unwrap();
52
53    let FunctionDecl {
54        until_fn,
55        _fn,
56        name,
57        until_body,
58        body,
59    } = fdecl;
60
61    quote::quote! {
62        #[::core::prelude::rust_2024::test]
63        #until_fn fn #name #until_body {
64            ::facet_testhelpers::setup();
65
66            #body
67        }
68    }
69    .into()
70}