macro_wasmer_universal_test/
lib.rs1use proc_macro2::{Ident, Span, TokenStream};
2use syn::{
3 parse::{Parse, ParseStream},
4 Attribute, Signature, Visibility,
5};
6
7#[proc_macro_attribute]
8pub fn universal_test(
9 _attr: proc_macro::TokenStream,
10 item: proc_macro::TokenStream,
11) -> proc_macro::TokenStream {
12 let MaybeItemFn {
13 outer_attrs,
14 inner_attrs,
15 vis,
16 sig,
17 block,
18 } = syn::parse_macro_input!(item as MaybeItemFn);
19
20 let fn_call = Ident::new(&sig.ident.to_string(), Span::call_site());
21 let fn_js_call = Ident::new(&format!("{}_js", sig.ident), Span::call_site());
22
23 let tokens = quote::quote! {
24 #[cfg(feature = "js")]
25 #[cfg_attr(feature = "js", wasm_bindgen_test)]
26 #(#outer_attrs) *
27 fn #fn_js_call() { #fn_call().unwrap(); }
28
29 #[cfg_attr(any(feature = "sys", feature = "jsc", feature = "wasm-c-api"), test)]
30 #(#outer_attrs) *
31 #vis #sig
32 {
33 #(#inner_attrs) *
34 #block
35 }
36 };
37
38 proc_macro::TokenStream::from(tokens)
39}
40
41#[derive(Debug, Clone)]
45struct MaybeItemFn {
46 outer_attrs: Vec<Attribute>,
47 inner_attrs: Vec<Attribute>,
48 vis: Visibility,
49 sig: Signature,
50 block: TokenStream,
51}
52
53impl Parse for MaybeItemFn {
56 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
57 let outer_attrs = input.call(Attribute::parse_outer)?;
58 let vis: Visibility = input.parse()?;
59 let sig: Signature = input.parse()?;
60 let inner_attrs = input.call(Attribute::parse_inner)?;
61 let block: TokenStream = input.parse()?;
62 Ok(Self {
63 outer_attrs,
64 inner_attrs,
65 vis,
66 sig,
67 block,
68 })
69 }
70}