1use crate::vector::NapiVector;
2use napi::bindgen_prelude::{ClassInstance, FromNapiValue};
3use napi_derive::napi;
4use paste::paste;
5use poly_commitment::commitment::PolyComm;
6use serde::{Deserialize, Serialize};
7
8macro_rules! impl_poly_comm {
9 (
10 $NapiG:ty,
11 $g:ty,
12 $field_name:ident
13 ) => {
14 paste! {
15 #[napi(js_name = [<"Wasm" $field_name "PolyComm">])]
16 #[derive(Clone, Debug, Serialize, Deserialize, Default)]
17 pub struct [<Napi $field_name:camel PolyComm>] {
18 #[napi(skip)]
19 pub unshifted: NapiVector<$NapiG>,
20 #[napi(skip)]
21 pub shifted: Option<$NapiG>,
22 }
23
24 #[napi]
25 impl [<Napi $field_name:camel PolyComm>] {
26 #[napi(constructor)]
27 pub fn new(unshifted: NapiVector<$NapiG>, shifted: Option<$NapiG>) -> Self {
28 assert!(
29 shifted.is_none(),
30 "mina#14628: Shifted commitments are deprecated and must not be used",
31 );
32 Self { unshifted, shifted }
33 }
34
35 #[napi(getter)]
36 pub fn unshifted(&self) -> NapiVector<$NapiG> {
37 self.unshifted.clone()
38 }
39
40 #[napi(setter, js_name = "set_unshifted")]
41 pub fn set_unshifted(&mut self, x: NapiVector<$NapiG>) {
42 self.unshifted = x;
43 }
44
45 #[napi(getter)]
46 pub fn shifted(&self) -> Option<$NapiG> {
47 self.shifted.clone()
48 }
49
50 #[napi(setter, js_name = "set_shifted")]
51 pub fn set_shifted(&mut self, value: Option<$NapiG>) {
52 self.shifted = value;
53 }
54 }
55
56 impl From<PolyComm<$g>> for [<Napi $field_name:camel PolyComm>] {
57 fn from(x: PolyComm<$g>) -> Self {
58 let PolyComm { chunks } = x;
59 let unshifted: Vec<$NapiG> = chunks.into_iter().map(Into::into).collect();
60 Self {
61 unshifted: unshifted.into(),
62 shifted: None,
63 }
64 }
65 }
66
67 impl From<&PolyComm<$g>> for [<Napi $field_name:camel PolyComm>] {
68 fn from(x: &PolyComm<$g>) -> Self {
69 let unshifted: Vec<$NapiG> = x.chunks.iter().map(|chunk| (*chunk).into()).collect();
70 Self {
71 unshifted: unshifted.into(),
72 shifted: None,
73 }
74 }
75 }
76
77 impl From<[<Napi $field_name:camel PolyComm>]> for PolyComm<$g> {
78 fn from(x: [<Napi $field_name:camel PolyComm>]) -> Self {
79 let [<Napi $field_name:camel PolyComm>] { unshifted, shifted } = x;
80 assert!(
81 shifted.is_none(),
82 "mina#14628: Shifted commitments are deprecated and must not be used",
83 );
84 PolyComm {
85 chunks: Vec::<$NapiG>::from(unshifted)
86 .into_iter()
87 .map(Into::into)
88 .collect(),
89 }
90 }
91 }
92
93 impl From<&[<Napi $field_name:camel PolyComm>]> for PolyComm<$g> {
94 fn from(x: &[<Napi $field_name:camel PolyComm>]) -> Self {
95 assert!(
96 x.shifted.is_none(),
97 "mina#14628: Shifted commitments are deprecated and must not be used",
98 );
99 PolyComm {
100 chunks: x
101 .unshifted
102 .iter()
103 .cloned()
104 .map(Into::into)
105 .collect(),
106 }
107 }
108 }
109
110 impl FromNapiValue for [<Napi $field_name:camel PolyComm>] {
111 unsafe fn from_napi_value(
112 env: napi::sys::napi_env,
113 napi_val: napi::sys::napi_value,
114 ) -> napi::Result<Self> {
115 let instance = <ClassInstance<[<Napi $field_name:camel PolyComm>]> as FromNapiValue>::from_napi_value(env, napi_val)?;
116 Ok((*instance).clone())
117 }
118 }
119
120 }
121 };
122}
123
124pub mod pallas {
125 use super::*;
126 use crate::wrappers::group::NapiGPallas;
127 use mina_curves::pasta::Pallas;
128
129 impl_poly_comm!(NapiGPallas, Pallas, Fq);
130}
131
132pub mod vesta {
133 use super::*;
134 use crate::wrappers::group::NapiGVesta;
135 use mina_curves::pasta::Vesta;
136
137 impl_poly_comm!(NapiGVesta, Vesta, Fp);
138}