nj_derive/generator/
napi.rs1use 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
10pub 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 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 raw_napi_function_template(
30 ident_n_api_fn,
31 quote! { #input_fn },
32 cb_args,
33 rust_invocation,
34 )
35 }
36}
37
38fn 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}