1 | #![allow (ambiguous_glob_reexports)] |
2 | |
3 | #[cfg (windows)] |
4 | macro_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))] |
71 | macro_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 | |
83 | mod functions; |
84 | mod types; |
85 | |
86 | pub use functions::*; |
87 | pub 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)] |
95 | pub unsafe fn setup() -> libloading::Library { |
96 | match load_all() { |
97 | Err(err) => panic!("{}" , err), |
98 | Ok(l) => l, |
99 | } |
100 | } |
101 | |