Skip to main content

emscripten_rs_macros/
lib.rs

1use proc_macro::TokenStream;
2use syn::parse2;
3
4use crate::em_js::{InlineJsInput, JsInputs, inline_js_impl, js_impl};
5
6mod em_js;
7
8#[proc_macro]
9pub fn js(input: TokenStream) -> TokenStream {
10    let tokens: proc_macro2::TokenStream = input.into();
11
12    parse2::<JsInputs>(tokens)
13        .and_then(js_impl)
14        .unwrap_or_else(|err| err.into_compile_error())
15        .into()
16}
17
18#[proc_macro]
19pub fn inline_js(input: TokenStream) -> TokenStream {
20    let tokens: proc_macro2::TokenStream = input.into();
21
22    parse2::<InlineJsInput>(tokens)
23        .and_then(inline_js_impl)
24        .unwrap_or_else(|err| err.into_compile_error())
25        .into()
26}
27
28#[cfg(test)]
29mod tests {
30    use crate::JsInputs;
31    use quote::quote;
32    use syn::parse2;
33
34    #[test]
35    fn simple() {
36        let input = quote! {fn f(){return 1;}
37        };
38        assert_eq!(
39            crate::js_impl(parse2::<JsInputs>(input).unwrap())
40                .unwrap()
41                .to_string(),
42            quote! {
43                mod _em_js_exports___em_js__f {
44                    #[used(linker)]
45                    #[unsafe(no_mangle)]
46                    #[allow(non_upper_case_globals)]
47                    static __em_js__f: [u8; 20usize] =
48                        *b"()<::>{return 1 ; }\0";
49                    std::arch::global_asm!(".globl __em_js__f");
50                }
51                #[link(wasm_import_module = "env")]
52                #[allow(dead_code)]
53                unsafe extern "C" {
54                    pub unsafe fn f();
55                }
56            }
57            .to_string()
58        )
59    }
60}