nj_derive/generator/
napi.rs

1use quote::quote;
2use proc_macro2::TokenStream;
3use syn::Ident;
4use syn::ItemFn;
5
6use crate::util::ident;
7use super::FnGeneratorCtx;
8use super::generate_rust_invocation;
9
10/// generate native code to be invoked by napi
11pub fn generate_napi_code(ctx: &FnGeneratorCtx, input_fn: &ItemFn) -> TokenStream {
12    let mut cb_args = vec![];
13    let rust_invocation = generate_rust_invocation(ctx, &mut cb_args);
14    let ident_n_api_fn = ident(&format!("napi_{}", ctx.fn_name()));
15
16    if ctx.is_method() {
17        // if function is method, we can't put rust function inside our napi because we need to preserver self
18        // in the rust method.
19        let napi_fn =
20            raw_napi_function_template(ident_n_api_fn, quote! {}, cb_args, rust_invocation);
21
22        quote! {
23            #input_fn
24
25            #napi_fn
26        }
27    } else {
28        // otherwise we can put rust function inside to make it tidy
29        raw_napi_function_template(
30            ident_n_api_fn,
31            quote! { #input_fn },
32            cb_args,
33            rust_invocation,
34        )
35    }
36}
37
38/// generate napi function invocation whether it is method or just free standing function
39fn raw_napi_function_template(
40    ident_n_api_fn: Ident,
41    input_fn: TokenStream,
42    rust_args_struct: Vec<TokenStream>,
43    rust_invocation: TokenStream,
44) -> TokenStream {
45    quote! {
46
47        extern "C" fn #ident_n_api_fn(env: node_bindgen::sys::napi_env,cb_info: node_bindgen::sys::napi_callback_info) -> node_bindgen::sys::napi_value
48        {
49            use node_bindgen::core::TryIntoJs;
50            use node_bindgen::core::IntoJs;
51            use node_bindgen::core::val::JsCallbackFunction;
52
53            node_bindgen::core::log::debug!( napi_fn = stringify!(#ident_n_api_fn),"invoking napi function");
54
55            #input_fn
56
57            #(#rust_args_struct)*
58
59            let js_env = node_bindgen::core::val::JsEnv::new(env);
60
61            #rust_invocation
62        }
63    }
64}