1#![allow(ambiguous_glob_reexports)]
4
5#[cfg(any(target_env = "msvc", feature = "dyn-symbols"))]
6macro_rules! generate {
7 (@stub_fn $name:ident($($param:ident: $ptype:ty,)*) -> napi_status) => {
8 unsafe extern "C" fn $name($(_: $ptype,)*) -> napi_status {
9 eprintln!("Node-API symbol {} has not been loaded", stringify!($name));
10 1
11 }
12 };
13 (@stub_fn $name:ident($($param:ident: $ptype:ty,)*) -> $rtype:ty) => {
14 unsafe extern "C" fn $name($(_: $ptype,)*) -> $rtype {
15 eprintln!("Node-API symbol {} has not been loaded", stringify!($name));
16 unsafe { std::mem::zeroed() }
17 }
18 };
19 (@stub_fn $name:ident($($param:ident: $ptype:ty,)*)) => {
20 unsafe extern "C" fn $name($(_: $ptype,)*) {
21 eprintln!("Node-API symbol {} has not been loaded", stringify!($name));
22 }
23 };
24 (extern "C" {
25 $(fn $name:ident($($param:ident: $ptype:ty$(,)?)*)$( -> $rtype:ty)?;)+
26 }) => {
27 struct Napi {
28 $(
29 $name: unsafe extern "C" fn(
30 $($param: $ptype,)*
31 )$( -> $rtype)*,
32 )*
33 }
34
35 static mut NAPI: Napi = {
36 $(
37 generate!(@stub_fn $name($($param: $ptype,)*) $( -> $rtype)?);
38 )*
39
40 Napi {
41 $(
42 $name,
43 )*
44 }
45 };
46
47 #[allow(clippy::missing_safety_doc)]
48 pub unsafe fn load(
49 host: &libloading::Library,
50 ) -> Result<(), libloading::Error> {
51 NAPI = Napi {
52 $(
53 $name: {
54 let symbol: Result<libloading::Symbol<unsafe extern "C" fn ($(_: $ptype,)*)$( -> $rtype)*>, libloading::Error> = host.get(stringify!($name).as_bytes());
55 match symbol {
56 Ok(f) => *f,
57 Err(e) => {
58 #[cfg(debug_assertions)] {
59 eprintln!("Load Node-API [{}] from host runtime failed: {}", stringify!($name), e);
60 }
61 NAPI.$name
62 }
63 }
64 },
65 )*
66 };
67
68 Ok(())
69 }
70
71 $(
72 #[inline]
73 #[allow(clippy::missing_safety_doc)]
74 pub unsafe fn $name($($param: $ptype,)*)$( -> $rtype)* {
75 (NAPI.$name)($($param,)*)
76 }
77 )*
78 };
79}
80
81#[cfg(not(any(target_env = "msvc", feature = "dyn-symbols")))]
82macro_rules! generate {
83 (extern "C" {
84 $(fn $name:ident($($param:ident: $ptype:ty$(,)?)*)$( -> $rtype:ty)?;)+
85 }) => {
86 extern "C" {
87 $(
88 pub fn $name($($param: $ptype,)*)$( -> $rtype)*;
89 ) *
90 }
91 };
92}
93
94mod functions;
95mod types;
96
97pub use functions::*;
98pub use types::*;
99
100#[cfg(any(target_env = "msvc", feature = "dyn-symbols"))]
105#[allow(clippy::missing_safety_doc)]
106pub unsafe fn setup() -> libloading::Library {
107 match load_all() {
108 Err(err) => panic!("{}", err),
109 Ok(l) => l,
110 }
111}