1use proc_macro::TokenStream;
2use proc_macro2::Span;
3use quote::quote;
4use syn::{Ident, ItemFn};
5
6#[proc_macro_attribute]
12pub fn sim(_args: TokenStream, input: TokenStream) -> TokenStream {
13 let input_fn = syn::parse_macro_input!(input as syn::ItemFn);
15
16 if input_fn.sig.asyncness.is_none() {
18 return syn::Error::new_spanned(input_fn.sig.fn_token, "sim functions must be async")
19 .to_compile_error()
20 .into();
21 }
22
23 expand_sim_fn(input_fn)
24}
25
26fn expand_sim_fn(input_fn: ItemFn) -> TokenStream {
27 let name = input_fn.sig.ident.clone();
28 let name_str = name.to_string();
29 let new_name = Ident::new(&format!("n0des_sim_{name}"), Span::call_site());
30 quote! {
31 #[tokio::test]
32 async fn #new_name() -> ::anyhow::Result<()> {
33 #input_fn
34
35 ::iroh_n0des::simulation::run_sim_fn(#name_str, #name).await
36 }
37 }
38 .into()
39}