camber-macros 0.1.0

Procedural macros for Camber
Documentation
use proc_macro::TokenStream;
use quote::quote;
use syn::{ItemFn, parse_macro_input};

/// Marks an async function as a Camber test.
///
/// Sets up a multi-thread Tokio runtime with Camber context installed.
/// The test body runs as an async block inside `camber::runtime::__test_async`.
///
/// ```ignore
/// #[camber::test]
/// async fn my_test() {
///     let handle = camber::spawn_async(async { 42 });
///     assert_eq!(handle.await.unwrap(), 42);
/// }
/// ```
#[proc_macro_attribute]
pub fn test(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let input = parse_macro_input!(item as ItemFn);

    let sig = &input.sig;
    let body = &input.block;
    let attrs = &input.attrs;
    let vis = &input.vis;
    let name = &sig.ident;

    match sig.asyncness {
        Some(_) => {}
        None => {
            return syn::Error::new_spanned(sig.fn_token, "camber::test requires an async fn")
                .to_compile_error()
                .into();
        }
    }

    let output = quote! {
        #[test]
        #(#attrs)*
        #vis fn #name() {
            camber::runtime::__test_async(|| async move #body)
                .expect("camber test runtime failed")
        }
    };

    output.into()
}