Skip to content

Commit f3ac1e4

Browse files
committed
napi: impls for wasm vectors
1 parent 410c80a commit f3ac1e4

File tree

2 files changed

+202
-1
lines changed

2 files changed

+202
-1
lines changed

plonk-napi/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
pub(crate) mod poseidon;
22
pub(crate) mod wrappers;
3+
pub(crate) mod wasm_vector;
34

45
pub use poseidon::{
56
caml_pasta_fp_poseidon_block_cipher,
67
caml_pasta_fq_poseidon_block_cipher,
78
};
89

910
pub use wrappers::field::{WasmPastaFp, WasmPastaFq};
10-
pub use wrappers::group::{WasmGPallas, WasmGVesta};
11+
pub use wrappers::group::{WasmGPallas, WasmGVesta};
12+
pub use wasm_vector::{fp::WasmVecVecFp, fq::WasmVecVecFq};

plonk-napi/src/wasm_vector.rs

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
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

Comments
 (0)