napi-rs/napi/src/lib.rs

113 lines
3.3 KiB
Rust
Raw Normal View History

mod async_work;
mod call_context;
mod env;
mod error;
mod js_values;
mod module;
#[cfg(all(feature = "libuv", napi4))]
mod promise;
mod status;
2018-04-28 17:26:38 +09:00
pub mod sys;
mod task;
#[cfg(napi4)]
pub mod threadsafe_function;
2020-07-08 01:59:09 +09:00
#[cfg(all(feature = "tokio_rt", napi4))]
mod tokio_rt;
#[cfg(all(feature = "libuv", napi4))]
mod uv;
mod version;
2018-04-28 17:26:38 +09:00
pub use async_work::AsyncWork;
2020-04-21 01:20:35 +09:00
pub use call_context::CallContext;
pub use env::*;
pub use error::{Error, Result};
pub use js_values::*;
pub use module::Module;
pub use status::Status;
pub use sys::napi_valuetype;
pub use task::Task;
pub use version::NodeVersion;
2018-04-28 17:26:38 +09:00
2020-07-08 01:59:09 +09:00
#[cfg(all(feature = "tokio_rt", napi4))]
pub use tokio_rt::shutdown as shutdown_tokio_rt;
2018-04-28 17:26:38 +09:00
#[macro_export]
macro_rules! register_module {
($module_name:ident, $init:ident) => {
2020-07-08 01:59:09 +09:00
#[inline]
fn check_status(code: $crate::sys::napi_status) -> Result<()> {
let status = Status::from(code);
match status {
Status::Ok => Ok(()),
_ => Err(Error::from_status(status)),
}
}
2018-04-28 17:26:38 +09:00
#[no_mangle]
#[cfg_attr(target_os = "linux", link_section = ".ctors")]
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
pub static __REGISTER_MODULE: extern "C" fn() = {
2020-07-08 01:59:09 +09:00
use std::ffi::CString;
2018-04-28 17:26:38 +09:00
use std::io::Write;
use std::os::raw::c_char;
use std::ptr;
use $crate::{sys, Env, JsObject, Module, NapiValue};
2018-04-28 17:26:38 +09:00
2020-07-08 01:59:09 +09:00
#[cfg(all(feature = "tokio_rt", napi4))]
use $crate::shutdown_tokio_rt;
2018-04-28 17:26:38 +09:00
extern "C" fn register_module() {
static mut MODULE_DESCRIPTOR: Option<sys::napi_module> = None;
unsafe {
MODULE_DESCRIPTOR = Some(sys::napi_module {
nm_version: 1,
nm_flags: 0,
nm_filename: concat!(file!(), "\0").as_ptr() as *const c_char,
nm_register_func: Some(init_module),
nm_modname: concat!(stringify!($module_name), "\0").as_ptr() as *const c_char,
nm_priv: 0 as *mut _,
reserved: [0 as *mut _; 4],
});
sys::napi_module_register(MODULE_DESCRIPTOR.as_mut().unwrap() as *mut sys::napi_module);
}
extern "C" fn init_module(
raw_env: sys::napi_env,
raw_exports: sys::napi_value,
) -> sys::napi_value {
let env = Env::from_raw(raw_env);
let mut exports: JsObject = JsObject::from_raw_unchecked(raw_env, raw_exports);
let mut cjs_module = Module { env, exports };
let result = $init(&mut cjs_module);
2018-04-28 17:26:38 +09:00
2020-07-08 01:59:09 +09:00
#[cfg(all(feature = "tokio_rt", napi4))]
let hook_result = check_status(unsafe {
sys::napi_add_env_cleanup_hook(raw_env, Some(shutdown_tokio_rt), ptr::null_mut())
});
#[cfg(not(all(feature = "tokio_rt", napi4)))]
let hook_result = Ok(());
match hook_result.and_then(move |_| result) {
2020-05-09 16:14:44 +09:00
Ok(_) => exports.into_raw(),
2018-04-28 17:26:38 +09:00
Err(e) => {
2020-05-09 16:14:44 +09:00
unsafe {
sys::napi_throw_error(
raw_env,
ptr::null(),
2020-07-08 01:59:09 +09:00
CString::from_vec_unchecked(format!("Error initializing module: {}", e).into())
.as_ptr() as *const _,
2020-05-09 16:14:44 +09:00
)
};
2018-04-28 17:26:38 +09:00
ptr::null_mut()
}
}
}
}
register_module
};
};
}