1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
//! Raw bindings to [Node-API][node-api]
//!
//! [Node-API][node-api] is Node.js's API for building native addons. Neon is
//! predominantly a safe wrapper for Node-API and most users should prefer the
//! the high level abstractions [outside](crate) of the sys module.
//!
//! However, directly using Node-API can be a useful tool for accessing low
//! level functionality not exposed by Neon or experimenting with extensions
//! to Neon without needing to fork the project.
//!
//! [node-api]: https://nodejs.org/api/n-api.html
//!
//! ## Initialization
//!
//! Before any Node-API functions may be used, [`setup`] must be called at
//! least once.
//!
//! ```rust,no_run
//! # #[cfg(feature = "sys")]
//! # {
//! # let env = std::ptr::null_mut().cast();
//! unsafe { neon::sys::setup(env); }
//! # }
//! ```
//! **Note**: It is unnecessary to call [`setup`] if
//! [`#[neon::main]`](crate::main) is used to initialize the addon.
//!
//! ## Safety
//!
//! The following are guidelines for ensuring safe usage of Node-API in Neon
//! but, do not represent a comprehensive set of safety rules. If possible,
//! users should avoid calling Neon methods or holding references to structures
//! created by Neon when calling Node-API functions directly.
//!
//! ### Env
//!
//! Neon ensures safety by carefully restricting access to [`Env`]
//! by wrapping it in a [`Context`](crate::context::Context). Usages of `Env`
//! should follow Neon's borrowing rules of `Context`.
//!
//! It is unsound to use an `Env` if Rust's borrowing rules would prevent usage
//! of the in scope `Context`.
//!
//! ### Values
//!
//! Neon [value types](crate::types) encapsulate references to
//! [JavaScript values](bindings::Value) with a _known type_. It is unsound to
//! construct a Neon value with a [`Value`] of the incorrect type.
//!
//! ## Example
//!
//! ```rust,no_run
//! # #[cfg(feature = "sys")]
//! # {
//! # let env = std::ptr::null_mut().cast();
//! use neon::{context::Cx, prelude::*, sys::bindings};
//!
//! let cx = unsafe {
//! neon::sys::setup(env);
//!
//! Cx::from_raw(env)
//! };
//!
//! let raw_string: bindings::Value = cx.string("Hello, World!").to_raw();
//! let js_string = unsafe { JsString::from_raw(&cx, raw_string) };
//! # }
//! ```
use std::{mem::MaybeUninit, sync::Once};
// Bindings are re-exported here to minimize changes.
// Follow-up issue: https://github.com/neon-bindings/neon/issues/982
pub(crate) use bindings::*;
pub(crate) mod array;
pub(crate) mod arraybuffer;
pub(crate) mod async_work;
pub(crate) mod buffer;
pub(crate) mod call;
pub(crate) mod convert;
pub(crate) mod error;
pub(crate) mod external;
pub(crate) mod fun;
pub(crate) mod mem;
pub(crate) mod no_panic;
pub(crate) mod object;
pub(crate) mod primitive;
pub(crate) mod promise;
pub(crate) mod raw;
pub(crate) mod reference;
pub(crate) mod scope;
pub(crate) mod string;
pub(crate) mod tag;
pub(crate) mod typedarray;
pub mod bindings;
#[cfg(feature = "napi-4")]
pub(crate) mod tsfn;
#[cfg(feature = "napi-5")]
pub(crate) mod date;
mod debug_send_wrapper;
#[cfg(feature = "napi-6")]
pub(crate) mod lifecycle;
/// Create a JavaScript `String`, panicking if unsuccessful
///
/// # Safety
/// * `env` is a `napi_env` valid for the current thread
/// * The returned value does not outlive `env`
unsafe fn string(env: Env, s: impl AsRef<str>) -> raw::Local {
let s = s.as_ref();
let mut result = MaybeUninit::uninit();
assert_eq!(
create_string_utf8(
env,
s.as_bytes().as_ptr() as *const _,
s.len(),
result.as_mut_ptr(),
),
Status::Ok,
);
result.assume_init()
}
static SETUP: Once = Once::new();
/// Loads Node-API symbols from the host process.
///
/// Must be called at least once before using any functions in bindings or
/// they will panic.
///
/// # Safety
/// `env` must be a valid `napi_env` for the current thread
pub unsafe fn setup(env: Env) {
SETUP.call_once(|| load(env).expect("Failed to load N-API symbols"));
}