nodex_api/
mac.rs

1// common macros
2#[macro_export]
3macro_rules! napi_module {
4    ($init:ident) => {
5        #[no_mangle]
6        pub unsafe extern "C" fn napi_register_module_v1(
7            env: $crate::api::napi_env,
8            exports: $crate::api::napi_value,
9        ) -> $crate::api::napi_value {
10            use $crate::value::NapiValueT;
11            let env = $crate::env::NapiEnv::from_raw(env);
12            let exports = $crate::value::JsObject::from_raw(env, exports);
13
14            // TODO: deal with exception
15            match std::panic::catch_unwind(move || $init(env, exports)) {
16                Ok(Ok(_)) => {}
17                Ok(Err(e)) => {
18                    env.throw_error(format!("napi: {:?}", e)).unwrap();
19                }
20                Err(e) => {
21                    env.throw_error(format!("panic: {:?}", e)).unwrap();
22                }
23            }
24
25            exports.raw()
26        }
27    };
28}
29
30#[macro_export]
31macro_rules! napi_call {
32    // [out] result: napi function which has output
33    (=$napi:ident, $($args:expr),+ $(,)?) => {
34        unsafe {
35            let mut result = std::mem::MaybeUninit::uninit();
36            let status = $crate::api::$napi($($args),+, result.as_mut_ptr());
37            if status.err() {
38                return Err(status);
39            }
40            result.assume_init()
41        }
42    };
43
44    (?$napi:ident, $($args:expr),+ $(,)?) => {
45        unsafe {
46            let mut result = std::mem::MaybeUninit::uninit();
47            let status = $crate::api::$napi($($args),+, result.as_mut_ptr());
48            (status, result.assume_init())
49        }
50    };
51
52    ($napi:ident, $($args:expr),+ $(,)?) => {
53        unsafe {
54            let status = $crate::api::$napi($($args),+);
55            if status.err() {
56                return Err(status);
57            } else {
58                NapiResult::Ok(())
59            }
60        }
61    }
62}
63
64#[macro_export]
65macro_rules! napi_guard {
66    ($version:expr) => {
67        assert!(
68            $version >= $crate::napi_version_guard(),
69            "Oops, your node(napi {}) is too old to support napi >= {}",
70            $version,
71            $crate::napi_version_guard(),
72        );
73    };
74}
75
76#[macro_export]
77macro_rules! napi_from_raw {
78    ($T:ident) => {
79        fn from_raw(env: $crate::env::NapiEnv, raw: $crate::api::napi_value) -> $T {
80            $T($crate::value::JsValue(env, raw))
81        }
82    };
83}
84
85#[macro_export]
86macro_rules! napi_get_value {
87    ($T:ident) => {
88        fn value(&self) -> $crate::value::JsValue {
89            self.0
90        }
91    };
92}
93
94#[macro_export]
95macro_rules! napi_value_t {
96    ($T:ident) => {
97        impl $crate::value::NapiValueT for $T {
98            napi_from_raw!($T);
99            napi_get_value!($T);
100        }
101    };
102}
103
104#[macro_export]
105macro_rules! napi_s {
106    ($s:expr) => {
107        std::ffi::CString::new($s).map_err(|_| $crate::NapiStatus::StringExpected)
108    };
109}
110
111#[macro_export]
112macro_rules! napi_r {
113    ($env:ident, =$s:expr) => {
114        match $s {
115            Ok(result) => result.raw(),
116            Err(err) => {
117                $env.throw_error(format!("{}", err)).unwrap();
118                $env.undefined().unwrap().raw()
119            }
120        }
121    };
122
123    ($env:ident, $s:expr) => {
124        match $s {
125            Ok(result) => $env.undefined().unwrap().raw(),
126            Err(err) => {
127                $env.throw_error(format!("{}", err)).unwrap();
128                $env.undefined().unwrap().raw()
129            }
130        }
131    };
132}
133
134#[macro_export]
135macro_rules! napi_as {
136    ($self:ident, $T:ty, $err:expr) => {{
137        let casted = unsafe { $self.cast::<$T>() };
138        if $self.check()? {
139            Ok(casted)
140        } else {
141            Err($err)
142        }
143    }};
144}
145
146#[macro_export]
147macro_rules! napi_is {
148    ($self:ident, $T:ty) => {
149        unsafe { $self.cast::<$T>() }.check()
150    };
151}