nj_derive/lib.rs
1#![allow(clippy::never_loop)]
2extern crate proc_macro;
3
4mod util;
5mod ast;
6mod generator;
7
8use proc_macro::TokenStream;
9
10/// This turns regular rust function into N-API compatible native module
11///
12/// For example; given rust following here
13/// ```ignore
14/// fn sum(first: i32, second: i32) -> i32 {
15/// return first+second
16/// }
17/// ```
18///
19/// into N-API module
20/// ```ignore
21/// #[no_mangle]
22/// pub extern "C" fn n_sum(env: napi_env, cb_info: napi_callback_info) -> napi_value {
23/// fn sum(first: i32, second: i32) -> i32 {
24/// return first+second
25/// }
26/// let js_env = JsEnv::new(env);
27/// let js_cb = result_to_napi!(js_env.get_cb_info(cb_info, 2),&js_env);
28/// let first = result_to_napi!(js_cb.get_value::<i32>(0),&js_env);
29/// let second = result_to_napi!(js_cb.get_value::<i32>(0),&js_env);
30/// sum(msg).into_js(&js_env)
31/// }
32/// ```
33#[proc_macro_attribute]
34pub fn node_bindgen(args: TokenStream, item: TokenStream) -> TokenStream {
35 use syn::AttributeArgs;
36
37 use ast::FunctionAttributes;
38 use ast::NodeItem;
39 use generator::generate_function;
40 use generator::generate_class;
41 use generator::generate_datatype;
42
43 let attribute_args = syn::parse_macro_input!(args as AttributeArgs);
44
45 let attribute: FunctionAttributes = match FunctionAttributes::from_ast(attribute_args) {
46 Ok(attr) => attr,
47 Err(err) => return err.to_compile_error().into(),
48 };
49
50 let parsed_item = syn::parse_macro_input!(item as NodeItem);
51
52 let out_express = match parsed_item {
53 NodeItem::Function(fn_item) => generate_function(fn_item, attribute),
54 NodeItem::Impl(impl_item) => generate_class(impl_item),
55 NodeItem::Derive(struct_item) => generate_datatype(struct_item),
56 };
57
58 // used for debugging, if error occurs println do not work so should uncomment express
59 // println!("{}", out_express);
60 // let out_express = quote::quote! {};
61
62 out_express.into()
63}