1#![allow(ambiguous_glob_reexports)]
2
3#[cfg(windows)]
4macro_rules! generate {
5 (extern "C" {
6 $(fn $name:ident($($param:ident: $ptype:ty$(,)?)*)$( -> $rtype:ty)?;)+
7 }) => {
8 struct Napi {
9 $(
10 $name: unsafe extern "C" fn(
11 $($param: $ptype,)*
12 )$( -> $rtype)*,
13 )*
14 }
15
16 #[inline(never)]
17 fn panic_load<T>() -> T {
18 panic!("Must load N-API bindings")
19 }
20
21 static mut NAPI: Napi = {
22 $(
23 unsafe extern "C" fn $name($(_: $ptype,)*)$( -> $rtype)* {
24 panic_load()
25 }
26 )*
27
28 Napi {
29 $(
30 $name,
31 )*
32 }
33 };
34
35 #[allow(clippy::missing_safety_doc)]
36 pub unsafe fn load(
37 host: &libloading::Library,
38 ) -> Result<(), libloading::Error> {
39 NAPI = Napi {
40 $(
41 $name: {
42 let symbol: Result<libloading::Symbol<unsafe extern "C" fn ($(_: $ptype,)*)$( -> $rtype)*>, libloading::Error> = host.get(stringify!($name).as_bytes());
43 match symbol {
44 Ok(f) => *f,
45 Err(e) => {
46 debug_assert!({
47 println!("Load Node-API [{}] from host runtime failed: {}", stringify!($name), e);
48 true
49 });
50 return Ok(());
51 }
52 }
53 },
54 )*
55 };
56
57 Ok(())
58 }
59
60 $(
61 #[inline]
62 #[allow(clippy::missing_safety_doc)]
63 pub unsafe fn $name($($param: $ptype,)*)$( -> $rtype)* {
64 (NAPI.$name)($($param,)*)
65 }
66 )*
67 };
68}
69
70#[cfg(not(windows))]
71macro_rules! generate {
72 (extern "C" {
73 $(fn $name:ident($($param:ident: $ptype:ty$(,)?)*)$( -> $rtype:ty)?;)+
74 }) => {
75 extern "C" {
76 $(
77 pub fn $name($($param: $ptype,)*)$( -> $rtype)*;
78 ) *
79 }
80 };
81}
82
83mod functions;
84mod types;
85
86pub use functions::*;
87pub use types::*;
88
89/// Loads N-API symbols from host process.
90/// Must be called at least once before using any functions in bindings or
91/// they will panic.
92/// Safety: `env` must be a valid `napi_env` for the current thread
93#[cfg(windows)]
94#[allow(clippy::missing_safety_doc)]
95pub unsafe fn setup() -> libloading::Library {
96 match load_all() {
97 Err(err) => panic!("{}", err),
98 Ok(l) => l,
99 }
100}
101