Skip to main content

kimchi_napi/wrappers/
field.rs

1use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
2use mina_curves::pasta::{Fp, Fq};
3use napi::bindgen_prelude::*;
4use serde::{Deserialize, Serialize};
5use wasm_types::FlatVectorElem;
6
7#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
8pub struct NapiPastaFp(pub Fp);
9
10#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
11pub struct NapiPastaFq(pub Fq);
12
13macro_rules! impl_field_wrapper {
14    ($name:ident, $field:ty) => {
15        impl $name {
16            fn from_bytes(bytes: &[u8]) -> Self {
17                let value =
18                    <$field>::deserialize_compressed(bytes).expect("deserialization failure");
19                Self(value)
20            }
21
22            fn to_bytes(self) -> Vec<u8> {
23                let mut bytes = Vec::with_capacity(core::mem::size_of::<$field>());
24                self.0
25                    .serialize_compressed(&mut bytes)
26                    .expect("serialization failure");
27                bytes
28            }
29        }
30
31        impl Serialize for $name {
32            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
33            where
34                S: serde::Serializer,
35            {
36                serializer.serialize_bytes(&self.to_bytes())
37            }
38        }
39        impl<'de> Deserialize<'de> for $name {
40            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
41            where
42                D: serde::Deserializer<'de>,
43            {
44                let bytes: Vec<u8> = Vec::<u8>::deserialize(deserializer)?;
45                <$field>::deserialize_compressed(bytes.as_slice())
46                    .map(Self)
47                    .map_err(serde::de::Error::custom)
48            }
49        }
50
51        impl From<$field> for $name {
52            fn from(value: $field) -> Self {
53                Self(value)
54            }
55        }
56
57        impl From<$name> for $field {
58            fn from(value: $name) -> Self {
59                value.0
60            }
61        }
62
63        impl<'a> From<&'a $name> for &'a $field {
64            fn from(value: &'a $name) -> Self {
65                &value.0
66            }
67        }
68
69        impl FlatVectorElem for $name {
70            const FLATTENED_SIZE: usize = core::mem::size_of::<$field>();
71
72            fn flatten(self) -> Vec<u8> {
73                self.to_bytes()
74            }
75
76            fn unflatten(flat: Vec<u8>) -> Self {
77                Self::from_bytes(&flat)
78            }
79        }
80
81        impl TypeName for $name {
82            fn type_name() -> &'static str {
83                <Buffer as TypeName>::type_name()
84            }
85
86            fn value_type() -> ValueType {
87                <Buffer as TypeName>::value_type()
88            }
89        }
90
91        impl ValidateNapiValue for $name {
92            unsafe fn validate(
93                env: sys::napi_env,
94                napi_val: sys::napi_value,
95            ) -> Result<sys::napi_value> {
96                <Buffer as ValidateNapiValue>::validate(env, napi_val)
97            }
98        }
99
100        impl FromNapiValue for $name {
101            unsafe fn from_napi_value(
102                env: sys::napi_env,
103                napi_val: sys::napi_value,
104            ) -> Result<Self> {
105                let buffer = <Buffer as FromNapiValue>::from_napi_value(env, napi_val)?;
106                Ok(Self::from_bytes(buffer.as_ref()))
107            }
108        }
109
110        impl ToNapiValue for $name {
111            unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
112                let buffer = Buffer::from(val.to_bytes());
113                <Buffer as ToNapiValue>::to_napi_value(env, buffer)
114            }
115        }
116
117        impl ToNapiValue for &mut $name {
118            unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
119                let buffer = Buffer::from(val.to_bytes());
120                <Buffer as ToNapiValue>::to_napi_value(env, buffer)
121            }
122        }
123    };
124}
125
126impl_field_wrapper!(NapiPastaFp, Fp);
127impl_field_wrapper!(NapiPastaFq, Fq);