napi_sys/
lib.rs

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