1+ use std:: { iter:: FromIterator , ops:: Deref } ;
2+
3+ use napi:: { bindgen_prelude:: * , sys} ;
4+ use wasm_types:: { FlatVector , FlatVectorElem } ;
5+
6+ #[ derive( Clone , Debug , Default ) ]
7+ pub struct WasmVector < T > ( pub Vec < T > ) ;
8+
9+ impl < T > WasmVector < T > {
10+ pub fn into_inner ( self ) -> Vec < T > {
11+ self . 0
12+ }
13+ }
14+
15+ impl < T > Deref for WasmVector < T > {
16+ type Target = Vec < T > ;
17+
18+ fn deref ( & self ) -> & Self :: Target {
19+ & self . 0
20+ }
21+ }
22+
23+ impl < T > From < Vec < T > > for WasmVector < T > {
24+ fn from ( value : Vec < T > ) -> Self {
25+ WasmVector ( value)
26+ }
27+ }
28+
29+ impl < T > From < WasmVector < T > > for Vec < T > {
30+ fn from ( value : WasmVector < T > ) -> Self {
31+ value. 0
32+ }
33+ }
34+
35+ impl < ' a , T > From < & ' a WasmVector < T > > for & ' a Vec < T > {
36+ fn from ( value : & ' a WasmVector < T > ) -> Self {
37+ & value. 0
38+ }
39+ }
40+
41+ impl < T > IntoIterator for WasmVector < T > {
42+ type Item = T ;
43+ type IntoIter = <Vec < T > as IntoIterator >:: IntoIter ;
44+
45+ fn into_iter ( self ) -> Self :: IntoIter {
46+ self . 0 . into_iter ( )
47+ }
48+ }
49+
50+ impl < ' a , T > IntoIterator for & ' a WasmVector < T > {
51+ type Item = & ' a T ;
52+ type IntoIter = <& ' a Vec < T > as IntoIterator >:: IntoIter ;
53+
54+ fn into_iter ( self ) -> Self :: IntoIter {
55+ self . 0 . iter ( )
56+ }
57+ }
58+
59+ impl < T > FromIterator < T > for WasmVector < T > {
60+ fn from_iter < I : IntoIterator < Item = T > > ( iter : I ) -> Self {
61+ WasmVector ( Vec :: from_iter ( iter) )
62+ }
63+ }
64+
65+ impl < T > Extend < T > for WasmVector < T > {
66+ fn extend < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
67+ self . 0 . extend ( iter) ;
68+ }
69+ }
70+
71+ impl < T > TypeName for WasmVector < T >
72+ where
73+ Vec < T > : TypeName ,
74+ {
75+ fn type_name ( ) -> & ' static str {
76+ <Vec < T > as TypeName >:: type_name ( )
77+ }
78+
79+ fn value_type ( ) -> ValueType {
80+ <Vec < T > as TypeName >:: value_type ( )
81+ }
82+ }
83+
84+ impl < T > ValidateNapiValue for WasmVector < T >
85+ where
86+ Vec < T > : ValidateNapiValue ,
87+ T : FromNapiValue ,
88+ {
89+ unsafe fn validate ( env : sys:: napi_env , napi_val : sys:: napi_value ) -> Result < sys:: napi_value > {
90+ <Vec < T > as ValidateNapiValue >:: validate ( env, napi_val)
91+ }
92+ }
93+
94+ impl < T > FromNapiValue for WasmVector < T >
95+ where
96+ Vec < T > : FromNapiValue ,
97+ {
98+ unsafe fn from_napi_value ( env : sys:: napi_env , napi_val : sys:: napi_value ) -> Result < Self > {
99+ Ok ( WasmVector ( <Vec < T > as FromNapiValue >:: from_napi_value (
100+ env, napi_val,
101+ ) ?) )
102+ }
103+ }
104+
105+ impl < T > ToNapiValue for WasmVector < T >
106+ where
107+ Vec < T > : ToNapiValue ,
108+ {
109+ unsafe fn to_napi_value ( env : sys:: napi_env , val : Self ) -> Result < sys:: napi_value > {
110+ <Vec < T > as ToNapiValue >:: to_napi_value ( env, val. 0 )
111+ }
112+ }
113+
114+ macro_rules! impl_vec_vec_fp {
115+ ( $name: ident, $field: ty, $wasm_field: ty) => {
116+ #[ napi]
117+ #[ derive( Clone , Debug , Default ) ]
118+ pub struct $name( #[ napi( skip) ] pub Vec <Vec <$field>>) ;
119+
120+ #[ napi]
121+ impl $name {
122+ #[ napi( constructor) ]
123+ pub fn create( capacity: i32 ) -> Self {
124+ Self ( Vec :: with_capacity( capacity as usize ) )
125+ }
126+
127+ #[ napi]
128+ pub fn push( & mut self , vector: Uint8Array ) -> Result <( ) > {
129+ let flattened = vector. as_ref( ) . to_vec( ) ;
130+ let values = FlatVector :: <$wasm_field>:: from_bytes( flattened)
131+ . into_iter( )
132+ . map( Into :: into)
133+ . collect( ) ;
134+ self . 0 . push( values) ;
135+ Ok ( ( ) )
136+ }
137+
138+ #[ napi]
139+ pub fn get( & self , index: i32 ) -> Result <Uint8Array > {
140+ let slice = self . 0 . get( index as usize ) . ok_or_else( || {
141+ Error :: new( Status :: InvalidArg , "index out of bounds" . to_string( ) )
142+ } ) ?;
143+
144+ let bytes = slice
145+ . iter( )
146+ . cloned( )
147+ . map( <$wasm_field>:: from)
148+ . flat_map( FlatVectorElem :: flatten)
149+ . collect:: <Vec <u8 >>( ) ;
150+
151+ Ok ( Uint8Array :: from( bytes) )
152+ }
153+
154+ #[ napi]
155+ pub fn set( & mut self , index: i32 , vector: Uint8Array ) -> Result <( ) > {
156+ let entry = self . 0 . get_mut( index as usize ) . ok_or_else( || {
157+ Error :: new( Status :: InvalidArg , "index out of bounds" . to_string( ) )
158+ } ) ?;
159+
160+ let flattened = vector. as_ref( ) . to_vec( ) ;
161+ * entry = FlatVector :: <$wasm_field>:: from_bytes( flattened)
162+ . into_iter( )
163+ . map( Into :: into)
164+ . collect( ) ;
165+ Ok ( ( ) )
166+ }
167+ }
168+
169+ impl From <Vec <Vec <$field>>> for $name {
170+ fn from( value: Vec <Vec <$field>>) -> Self {
171+ Self ( value)
172+ }
173+ }
174+
175+ impl From <$name> for Vec <Vec <$field>> {
176+ fn from( value: $name) -> Self {
177+ value. 0
178+ }
179+ }
180+ } ;
181+ }
182+
183+ pub mod fp {
184+ use super :: * ;
185+ use crate :: wrappers:: field:: WasmPastaFp ;
186+ use mina_curves:: pasta:: Fp ;
187+ use napi_derive:: napi;
188+
189+ impl_vec_vec_fp ! ( WasmVecVecFp , Fp , WasmPastaFp ) ;
190+ }
191+
192+ pub mod fq {
193+ use super :: * ;
194+ use crate :: wrappers:: field:: WasmPastaFq ;
195+ use mina_curves:: pasta:: Fq ;
196+ use napi_derive:: napi;
197+
198+ impl_vec_vec_fp ! ( WasmVecVecFq , Fq , WasmPastaFq ) ;
199+ }
0 commit comments