1use crate::{api, env::NapiEnv, prelude::*};
2
3#[derive(Debug, Clone)]
5pub struct JsArgs(pub Vec<JsValue>);
6
7pub trait ToJsArgs {
9 fn to_js_args(self, env: NapiEnv) -> NapiResult<JsArgs>;
10 fn len() -> usize;
11}
12
13pub trait FromJsArgs: Sized {
15 fn from_js_args(args: JsArgs) -> NapiResult<Self>;
16 fn len() -> usize;
17}
18
19impl FromJsArgs for () {
20 fn from_js_args(args: JsArgs) -> NapiResult<()> {
21 Ok(())
22 }
23
24 fn len() -> usize {
25 0
26 }
27}
28
29impl ToJsArgs for () {
30 fn to_js_args(self, env: NapiEnv) -> NapiResult<JsArgs> {
31 Ok(JsArgs(vec![]))
32 }
33
34 fn len() -> usize {
35 0
36 }
37}
38
39impl<T: NapiValueT> FromJsArgs for T {
40 fn from_js_args(args: JsArgs) -> NapiResult<T> {
41 let arg = unsafe { args.0.get_unchecked(0) };
43 let casted = unsafe { arg.cast::<T>() };
44 match casted.check() {
45 Ok(true) => Ok(casted),
46 Ok(false) => Err(NapiStatus::InvalidArg),
47 Err(e) => Err(e),
48 }
49 }
50
51 fn len() -> usize {
52 1
53 }
54}
55
56impl<T: NapiValueT> ToJsArgs for T {
57 fn to_js_args(self, env: NapiEnv) -> NapiResult<JsArgs> {
58 Ok(JsArgs(vec![self.value()]))
59 }
60
61 fn len() -> usize {
62 1
63 }
64}
65
66macro_rules! count {
67 () => (0_usize);
68 ($x:tt $($xs:tt)*) => (1_usize + count!($($xs)*));
69}
70
71#[macro_export]
72macro_rules! from_js_args_tuple {
73 () => ();
74
75 ($($name:ident),+; $($idx:tt),+) => (
76 #[doc(hidden)]
77 impl<$($name: NapiValueT + NapiValueCheck),*> FromJsArgs for ($($name,)*) {
78 fn from_js_args(args: JsArgs) -> NapiResult<Self> {
79 Ok(($({
80 let arg = unsafe { args.0.get_unchecked($idx) };
82 let casted = unsafe { arg.cast::<$name>() };
83
84 match casted.check() {
85 Ok(true) => {
86 casted
87 }
88 Ok(false) => {
89 return Err(NapiStatus::InvalidArg)
90 }
91 Err(e) => {
92 return Err(e)
93 }
94 }
95 },)*))
96 }
97
98 fn len() -> usize {
99 count!($($name)*)
100 }
101 }
102 )
103}
104
105from_js_args_tuple!(T0; 0);
106from_js_args_tuple!(T0, T1; 0, 1);
107from_js_args_tuple!(T0, T1, T2; 0, 1, 2);
108from_js_args_tuple!(T0, T1, T2, T3; 0, 1, 2, 3);
109from_js_args_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4);
110from_js_args_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5);
111from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6);
112from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 6);
113from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8);
114from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
115from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
116from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
117from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
118from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
119from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
120from_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
121
122#[macro_export]
123macro_rules! to_js_args_tuple {
124 () => ();
125
126 ($($name:ident),+; $($idx:tt),+) => (
127 #[doc(hidden)]
128 impl<$($name: NapiValueT + NapiValueCheck),+> ToJsArgs for ($($name,)+) {
129 fn to_js_args(self, env: NapiEnv) -> NapiResult<JsArgs> {
130 let mut args = vec![];
131 let mut idx = 0;
132
133 $({
134 args.push(self.$idx.value());
135 })+
136
137 Ok(JsArgs(args))
138 }
139
140 fn len() -> usize {
141 count!($($name)*)
142 }
143 }
144 )
145}
146
147to_js_args_tuple!(T0; 0);
148to_js_args_tuple!(T0, T1; 0, 1);
149to_js_args_tuple!(T0, T1, T2; 0, 1, 2);
150to_js_args_tuple!(T0, T1, T2, T3; 0, 1, 2, 3);
151to_js_args_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4);
152to_js_args_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5);
153to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6);
154to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 6);
155to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8);
156to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
157to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
158to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
159to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
160to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
161to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
162to_js_args_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);