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