1use napi::{bindgen_prelude::*, sys};
2use serde::{Deserialize, Serialize};
3use std::{iter::FromIterator, ops::Deref};
4use wasm_types::{FlatVector, FlatVectorElem};
5
6#[derive(Clone, Debug, Default)]
7pub struct NapiFlatVector<T>(pub Vec<T>);
8
9impl<T> NapiFlatVector<T> {
10 pub fn into_inner(self) -> Vec<T> {
11 self.0
12 }
13}
14
15impl<T: FlatVectorElem> NapiFlatVector<T> {
16 pub fn from_bytes(bytes: Vec<u8>) -> Self {
17 let flat: FlatVector<T> = FlatVector::from_bytes(bytes);
18 NapiFlatVector(flat.into())
19 }
20
21 pub fn into_bytes(self) -> Vec<u8> {
22 self.0
23 .into_iter()
24 .flat_map(FlatVectorElem::flatten)
25 .collect()
26 }
27}
28
29impl<T> Deref for NapiFlatVector<T> {
30 type Target = Vec<T>;
31
32 fn deref(&self) -> &Self::Target {
33 &self.0
34 }
35}
36
37impl<T> From<Vec<T>> for NapiFlatVector<T> {
38 fn from(value: Vec<T>) -> Self {
39 NapiFlatVector(value)
40 }
41}
42
43impl<T> From<NapiFlatVector<T>> for Vec<T> {
44 fn from(value: NapiFlatVector<T>) -> Self {
45 value.0
46 }
47}
48
49impl<T> From<FlatVector<T>> for NapiFlatVector<T> {
50 fn from(value: FlatVector<T>) -> Self {
51 NapiFlatVector(value.into())
52 }
53}
54
55impl<T> From<NapiFlatVector<T>> for FlatVector<T> {
56 fn from(value: NapiFlatVector<T>) -> Self {
57 FlatVector::from(value.0)
58 }
59}
60
61impl<'a, T> From<&'a NapiFlatVector<T>> for &'a Vec<T> {
62 fn from(value: &'a NapiFlatVector<T>) -> Self {
63 &value.0
64 }
65}
66
67impl<T> IntoIterator for NapiFlatVector<T> {
68 type Item = T;
69 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
70
71 fn into_iter(self) -> Self::IntoIter {
72 self.0.into_iter()
73 }
74}
75
76impl<'a, T> IntoIterator for &'a NapiFlatVector<T> {
77 type Item = &'a T;
78 type IntoIter = <&'a Vec<T> as IntoIterator>::IntoIter;
79
80 fn into_iter(self) -> Self::IntoIter {
81 self.0.iter()
82 }
83}
84
85impl<T> FromIterator<T> for NapiFlatVector<T> {
86 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
87 NapiFlatVector(Vec::from_iter(iter))
88 }
89}
90
91impl<T> Extend<T> for NapiFlatVector<T> {
92 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
93 self.0.extend(iter);
94 }
95}
96
97impl<T> TypeName for NapiFlatVector<T>
98where
99 Vec<u8>: TypeName,
100{
101 fn type_name() -> &'static str {
102 <Vec<u8> as TypeName>::type_name()
103 }
104
105 fn value_type() -> ValueType {
106 <Vec<u8> as TypeName>::value_type()
107 }
108}
109
110impl<T> ValidateNapiValue for NapiFlatVector<T>
111where
112 Vec<u8>: ValidateNapiValue,
113 Uint8Array: ValidateNapiValue,
114{
115 unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> {
116 if <Uint8Array as ValidateNapiValue>::validate(env, napi_val).is_ok() {
119 return Ok(napi_val);
120 }
121 <Vec<u8> as ValidateNapiValue>::validate(env, napi_val)
122 }
123}
124
125impl<T> FromNapiValue for NapiFlatVector<T>
126where
127 T: FlatVectorElem,
128{
129 unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
130 let bytes = if let Ok(arr) = <Uint8Array as FromNapiValue>::from_napi_value(env, napi_val) {
132 arr.as_ref().to_vec()
133 } else {
134 <Vec<u8> as FromNapiValue>::from_napi_value(env, napi_val)?
135 };
136 Ok(NapiFlatVector::from_bytes(bytes))
137 }
138}
139
140impl<T> ToNapiValue for NapiFlatVector<T>
141where
142 T: FlatVectorElem,
143{
144 unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
145 let bytes = val.into_bytes();
146 <Uint8Array as ToNapiValue>::to_napi_value(env, Uint8Array::from(bytes))
147 }
148}
149
150impl<T> ToNapiValue for &NapiFlatVector<T>
151where
152 T: FlatVectorElem + Clone,
153{
154 unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
155 let bytes = val
156 .0
157 .clone()
158 .into_iter()
159 .flat_map(FlatVectorElem::flatten)
160 .collect::<Vec<_>>();
161 <Uint8Array as ToNapiValue>::to_napi_value(env, Uint8Array::from(bytes))
162 }
163}
164
165impl<T> ToNapiValue for &mut NapiFlatVector<T>
166where
167 T: FlatVectorElem + Clone,
168{
169 unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
170 let bytes = val
171 .0
172 .clone()
173 .into_iter()
174 .flat_map(FlatVectorElem::flatten)
175 .collect::<Vec<_>>();
176 <Uint8Array as ToNapiValue>::to_napi_value(env, Uint8Array::from(bytes))
177 }
178}
179
180#[derive(Clone, Debug, Serialize, Deserialize, Default)]
181pub struct NapiVector<T>(pub Vec<T>);
182
183impl<T> NapiVector<T> {
184 pub fn into_inner(self) -> Vec<T> {
185 self.0
186 }
187}
188
189impl<T> Deref for NapiVector<T> {
190 type Target = Vec<T>;
191
192 fn deref(&self) -> &Self::Target {
193 &self.0
194 }
195}
196
197impl<T> From<Vec<T>> for NapiVector<T> {
198 fn from(value: Vec<T>) -> Self {
199 NapiVector(value)
200 }
201}
202
203impl<T> From<NapiVector<T>> for Vec<T> {
204 fn from(value: NapiVector<T>) -> Self {
205 value.0
206 }
207}
208
209impl<'a, T> From<&'a NapiVector<T>> for &'a Vec<T> {
210 fn from(value: &'a NapiVector<T>) -> Self {
211 &value.0
212 }
213}
214
215impl<T> IntoIterator for NapiVector<T> {
216 type Item = T;
217 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
218
219 fn into_iter(self) -> Self::IntoIter {
220 self.0.into_iter()
221 }
222}
223
224impl<'a, T> IntoIterator for &'a NapiVector<T> {
225 type Item = &'a T;
226 type IntoIter = <&'a Vec<T> as IntoIterator>::IntoIter;
227
228 fn into_iter(self) -> Self::IntoIter {
229 self.0.iter()
230 }
231}
232
233impl<T> FromIterator<T> for NapiVector<T> {
234 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
235 NapiVector(Vec::from_iter(iter))
236 }
237}
238
239impl<T> Extend<T> for NapiVector<T> {
240 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
241 self.0.extend(iter);
242 }
243}
244
245impl<T> TypeName for NapiVector<T>
246where
247 Vec<T>: TypeName,
248{
249 fn type_name() -> &'static str {
250 <Vec<T> as TypeName>::type_name()
251 }
252
253 fn value_type() -> ValueType {
254 <Vec<T> as TypeName>::value_type()
255 }
256}
257
258impl<T> ValidateNapiValue for NapiVector<T>
259where
260 Vec<T>: ValidateNapiValue,
261 T: FromNapiValue,
262{
263 unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> {
264 <Vec<T> as ValidateNapiValue>::validate(env, napi_val)
265 }
266}
267
268impl<T> FromNapiValue for NapiVector<T>
269where
270 Vec<T>: FromNapiValue,
271{
272 unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
273 Ok(NapiVector(<Vec<T> as FromNapiValue>::from_napi_value(
274 env, napi_val,
275 )?))
276 }
277}
278
279impl<T> ToNapiValue for NapiVector<T>
280where
281 Vec<T>: ToNapiValue,
282{
283 unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
284 <Vec<T> as ToNapiValue>::to_napi_value(env, val.0)
285 }
286}
287
288impl<T> ToNapiValue for &NapiVector<T>
289where
290 Vec<T>: ToNapiValue,
291 T: Clone,
292{
293 unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
294 let cloned: Vec<T> = val.0.clone();
295 <Vec<T> as ToNapiValue>::to_napi_value(env, cloned)
296 }
297}
298
299impl<T> ToNapiValue for &mut NapiVector<T>
300where
301 Vec<T>: ToNapiValue,
302 T: Clone,
303{
304 unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
305 let cloned: Vec<T> = val.0.clone();
306 <Vec<T> as ToNapiValue>::to_napi_value(env, cloned)
307 }
308}
309
310macro_rules! impl_vec_vec {
311 ($name:ident, $field:ty, $napi_field:ty, $wasm_vec_vec:literal) => {
312 #[napi(js_name = $wasm_vec_vec)]
313 #[derive(Clone, Debug, Default)]
314 pub struct $name(#[napi(skip)] pub Vec<Vec<$field>>);
315
316 #[napi]
317 impl $name {
318 #[napi(constructor)]
319 pub fn new(capacity: i32) -> Self {
320 $name(Vec::with_capacity(capacity as usize))
321 }
322
323 #[napi]
324 pub fn push(&mut self, vector: Uint8Array) -> Result<()> {
325 let flattened = vector.as_ref().to_vec();
326 let values = FlatVector::<$napi_field>::from_bytes(flattened)
327 .into_iter()
328 .map(Into::into)
329 .collect();
330 self.0.push(values);
331 Ok(())
332 }
333
334 #[napi]
335 pub fn get(&self, index: i32) -> Result<Uint8Array> {
336 let slice = self.0.get(index as usize).ok_or_else(|| {
337 Error::new(Status::InvalidArg, "index out of bounds".to_string())
338 })?;
339
340 let bytes = slice
341 .iter()
342 .cloned()
343 .map(<$napi_field>::from)
344 .flat_map(FlatVectorElem::flatten)
345 .collect::<Vec<u8>>();
346
347 Ok(Uint8Array::from(bytes))
348 }
349
350 #[napi]
351 pub fn set(&mut self, index: i32, vector: Uint8Array) -> Result<()> {
352 let entry = self.0.get_mut(index as usize).ok_or_else(|| {
353 Error::new(Status::InvalidArg, "index out of bounds".to_string())
354 })?;
355
356 let flattened = vector.as_ref().to_vec();
357 *entry = FlatVector::<$napi_field>::from_bytes(flattened)
358 .into_iter()
359 .map(Into::into)
360 .collect();
361 Ok(())
362 }
363 }
364
365 impl FromNapiValue for $name {
366 unsafe fn from_napi_value(
367 env: sys::napi_env,
368 napi_val: sys::napi_value,
369 ) -> Result<Self> {
370 let instance =
371 <ClassInstance<$name> as FromNapiValue>::from_napi_value(env, napi_val)?;
372 Ok((*instance).clone())
373 }
374 }
375
376 impl From<Vec<Vec<$field>>> for $name {
377 fn from(value: Vec<Vec<$field>>) -> Self {
378 Self(value)
379 }
380 }
381
382 impl From<$name> for Vec<Vec<$field>> {
383 fn from(value: $name) -> Self {
384 value.0
385 }
386 }
387 };
388}
389
390pub mod fp {
391 use super::*;
392 use crate::wrappers::field::NapiPastaFp;
393 use mina_curves::pasta::Fp;
394 use napi_derive::napi;
395
396 impl_vec_vec!(NapiVecVecFp, Fp, NapiPastaFp, "WasmVecVecFp");
397}
398
399pub mod fq {
400 use super::*;
401 use crate::wrappers::field::NapiPastaFq;
402 use mina_curves::pasta::Fq;
403 use napi_derive::napi;
404
405 impl_vec_vec!(NapiVecVecFq, Fq, NapiPastaFq, "WasmVecVecFq");
406}