lib.rs

 1use std::mem;
 2
 3use proc_macro::TokenStream;
 4use quote::{format_ident, quote};
 5use syn::{parse_macro_input, ItemFn};
 6
 7#[proc_macro_attribute]
 8pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
 9    assert!(args.is_empty());
10
11    let mut inner_fn = parse_macro_input!(function as ItemFn);
12    let inner_fn_name = format_ident!("_{}", inner_fn.sig.ident);
13    let outer_fn_name = mem::replace(&mut inner_fn.sig.ident, inner_fn_name.clone());
14    let outer_fn = if inner_fn.sig.asyncness.is_some() {
15        quote! {
16            #[test]
17            fn #outer_fn_name() {
18                #inner_fn
19
20                gpui::App::test_async((), move |ctx| async {
21                    #inner_fn_name(ctx).await;
22                });
23            }
24        }
25    } else {
26        quote! {
27            #[test]
28            fn #outer_fn_name() {
29                #inner_fn
30
31                gpui::App::test((), |ctx| {
32                    #inner_fn_name(ctx);
33                });
34            }
35        }
36    };
37
38    TokenStream::from(outer_fn)
39}