purewasm_proc_macro/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemFn, PatType};
4
5#[proc_macro_attribute]
6pub fn purewasm_bindgen(_args: TokenStream, input: TokenStream) -> TokenStream {
7    let function = parse_macro_input!(input as ItemFn);
8    let function_name = &function.sig.ident;
9    if function.sig.inputs.len() != 1 {
10        return TokenStream::from(quote! {
11            compile_error!("There should be one(only) input parameter");
12        });
13    }
14
15    let input_type = match &function.sig.inputs[0] {
16        syn::FnArg::Typed(PatType { ty, .. }) => ty,
17        _ => unreachable!()
18    };
19
20    let output_type = match &function.sig.output {
21        syn::ReturnType::Type(_, ty) => ty,
22        _ => unreachable!()
23    };
24    
25    
26    let output = quote! {
27        pub mod #function_name {
28            use super::*;
29            mod inner {
30                use super::*;
31                #function
32            }
33
34            #[no_mangle]
35            pub unsafe extern "C" fn #function_name(ptr: *mut u8, len: i32) -> (i32, i32) {
36                let memory = WasmMemory {
37                    codec: purewasm::DefaultCodec,
38                };
39                let input: Result<#input_type, PureError> = memory.from_memory(ptr, len);
40                if let Ok(input) = input {
41                    let result = inner::#function_name(input);
42                    memory.to_memory(result)
43                } else {
44                    let r: #output_type = PureResult::Err(PureError::new("NO_INPUT"));
45                    return memory.to_memory(r);
46                }
47            }
48        }
49    };
50    output.into()
51}