kimchi_stubs/
field_vector.rs

1//! We implement a custom type for field vectors in order to quickly build field
2//! vectors from the OCaml side and avoid large vector clones.
3
4use paste::paste;
5
6macro_rules! impl_vector_old {
7    ($name: ident, $CamlF: ty, $F: ty) => {
8
9        impl_caml_pointer!($name => Vec<$F>);
10
11        paste! {
12            #[ocaml_gen::func]
13            #[ocaml::func]
14            pub fn [<$name:snake _create>]() -> $name {
15                $name::create(Vec::new())
16            }
17
18            #[ocaml_gen::func]
19            #[ocaml::func]
20            pub fn [<$name:snake _length>](v: $name) -> ocaml::Int {
21                v.len() as isize
22            }
23
24            #[ocaml_gen::func]
25            #[ocaml::func]
26            pub fn [<$name:snake _emplace_back>](mut v: $name, x: $CamlF) {
27                (*v).push(x.into());
28            }
29
30            #[ocaml_gen::func]
31            #[ocaml::func]
32            pub fn [<$name:snake _get>](
33                v: $name,
34                i: ocaml::Int,
35            ) -> Result<$CamlF, ocaml::Error> {
36                match v.get(i as usize) {
37                    Some(x) => Ok(x.into()),
38                    None => Err(ocaml::Error::invalid_argument("vector_get")
39                        .err()
40                        .unwrap()),
41                }
42            }
43
44            #[ocaml_gen::func]
45            #[ocaml::func]
46            pub fn [<$name:snake _set>](
47                mut v: $name,
48                i: ocaml::Int,
49                value: $CamlF,
50            ) -> Result<(), ocaml::Error> {
51                match v.get_mut(i as usize) {
52                    Some(x) => Ok(*x = value.into()),
53                    None => Err(ocaml::Error::invalid_argument("vector_set")
54                        .err()
55                        .unwrap()),
56                }
57            }
58        }
59    };
60}
61
62#[allow(unused_macros)]
63macro_rules! impl_vector {
64    ($name: ident, $CamlF: ty, $F: ty) => {
65
66        impl_shared_rwlock!($name => Vec<$F>);
67
68        paste! {
69            #[ocaml_gen::func]
70            #[ocaml::func]
71            pub fn [<$name:snake _create>]() -> $name {
72                $name::new(Vec::new())
73            }
74
75            #[ocaml_gen::func]
76            #[ocaml::func]
77            pub fn [<$name:snake _length>](v: $name) -> Result<ocaml::Int, ocaml::Error> {
78                let v = v.read().map_err(|_| ocaml::CamlError::Failure("vector_length: could not capture lock"))?;
79                Ok(v.len() as isize)
80            }
81
82            #[ocaml_gen::func]
83            #[ocaml::func]
84            pub fn [<$name:snake _emplace_back>](v: $name, x: $CamlF) -> Result<(), ocaml::Error> {
85                let mut v = v.write().map_err(|_| ocaml::CamlError::Failure("vector_emplace_back: could not capture lock"))?;
86                v.push(x.into());
87                Ok(())
88            }
89
90            #[ocaml_gen::func]
91            #[ocaml::func]
92            pub fn [<$name:snake _get>](
93                v: $name,
94                i: ocaml::Int,
95            ) -> Result<$CamlF, ocaml::Error> {
96                let v = v.read().map_err(|_| ocaml::CamlError::Failure("vector_get: could not capture lock"))?;
97                match v.get(i as usize) {
98                    Some(x) => Ok(x.into()),
99                    None => Err(ocaml::Error::invalid_argument("vector_get")
100                        .err()
101                        .unwrap()),
102                }
103            }
104
105            #[ocaml_gen::func]
106            #[ocaml::func]
107            pub fn [<$name:snake _set>](
108                v: $name,
109                i: ocaml::Int,
110                value: $CamlF,
111            ) -> Result<(), ocaml::Error> {
112                let mut v = v.write().map_err(|_| ocaml::CamlError::Failure("vector_set: could not capture lock"))?;
113                match v.get_mut(i as usize) {
114                    Some(x) => Ok(*x = value.into()),
115                    None => Err(ocaml::Error::invalid_argument("vector_set")
116                        .err()
117                        .unwrap()),
118                }
119            }
120        }
121    }
122}
123
124pub mod fp {
125    use super::*;
126    use crate::arkworks::CamlFp;
127    use mina_curves::pasta::Fp;
128
129    impl_vector_old!(CamlFpVector, CamlFp, Fp);
130}
131
132pub mod fq {
133    use super::*;
134    use crate::arkworks::CamlFq;
135    use mina_curves::pasta::Fq;
136
137    impl_vector_old!(CamlFqVector, CamlFq, Fq);
138}