Skip to main content

ark_serialize/
serde.rs

1use ark_std::ops::{Deref, DerefMut};
2
3#[cfg(feature = "serde")]
4use ::serde::{Deserializer, Serializer};
5#[cfg(feature = "serde")]
6use ark_std::string::ToString;
7
8use crate::*;
9
10/// A serde-compatible wrapper that forces compression and skips validation.
11#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
12pub struct CompressedUnchecked<T>(pub T);
13
14/// A serde-compatible wrapper that skips compression and skips validation.
15#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
16pub struct UncompressedUnchecked<T>(pub T);
17
18/// A serde-compatible wrapper that forces compression and validates.
19#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
20pub struct CompressedChecked<T>(pub T);
21
22/// A serde-compatible wrapper that skips compression and forces validation.
23#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
24pub struct UncompressedChecked<T>(pub T);
25
26#[cfg(feature = "serde")]
27pub fn serialize<S: Serializer>(
28    value: &impl CanonicalSerialize,
29    compress: Compress,
30    s: S,
31) -> Result<S::Ok, S::Error> {
32    use ::serde::Serialize;
33    match compress {
34        Compress::Yes => CompressedUnchecked(value).serialize(s),
35        Compress::No => UncompressedUnchecked(value).serialize(s),
36    }
37}
38
39#[cfg(feature = "serde")]
40pub fn deserialize<'de, T: CanonicalDeserialize, D: Deserializer<'de>>(
41    d: D,
42    compress: Compress,
43    checked: Validate,
44) -> Result<T, D::Error> {
45    use ::serde::Deserialize;
46    match (checked, compress) {
47        (Validate::Yes, Compress::Yes) => CompressedChecked::<T>::deserialize(d).map(|val| val.0),
48        (Validate::No, Compress::Yes) => CompressedUnchecked::<T>::deserialize(d).map(|val| val.0),
49        (Validate::Yes, Compress::No) => UncompressedChecked::<T>::deserialize(d).map(|val| val.0),
50        (Validate::No, Compress::No) => UncompressedUnchecked::<T>::deserialize(d).map(|val| val.0),
51    }
52}
53
54#[cfg(feature = "serde")]
55pub fn serialize_compressed<S: Serializer>(
56    value: &impl CanonicalSerialize,
57    s: S,
58) -> Result<S::Ok, S::Error> {
59    serialize(value, Compress::Yes, s)
60}
61
62#[cfg(feature = "serde")]
63pub fn serialize_uncompressed<S: Serializer>(
64    value: &impl CanonicalSerialize,
65    s: S,
66) -> Result<S::Ok, S::Error> {
67    serialize(value, Compress::No, s)
68}
69
70#[cfg(feature = "serde")]
71pub fn deserialize_compressed_checked<'de, T: CanonicalDeserialize, D: Deserializer<'de>>(
72    d: D,
73) -> Result<T, D::Error> {
74    deserialize(d, Compress::Yes, Validate::Yes)
75}
76
77#[cfg(feature = "serde")]
78pub fn deserialize_uncompressed_checked<'de, T: CanonicalDeserialize, D: Deserializer<'de>>(
79    d: D,
80) -> Result<T, D::Error> {
81    deserialize(d, Compress::No, Validate::Yes)
82}
83
84#[cfg(feature = "serde")]
85pub fn deserialize_compressed_unchecked<'de, T: CanonicalDeserialize, D: Deserializer<'de>>(
86    d: D,
87) -> Result<T, D::Error> {
88    deserialize(d, Compress::Yes, Validate::No)
89}
90
91#[cfg(feature = "serde")]
92pub fn deserialize_uncompressed_unchecked<'de, T: CanonicalDeserialize, D: Deserializer<'de>>(
93    d: D,
94) -> Result<T, D::Error> {
95    deserialize(d, Compress::No, Validate::No)
96}
97
98macro_rules! impl_ops {
99    ($type:ty, $cons:expr) => {
100        impl<T> Deref for $type {
101            type Target = T;
102
103            fn deref(&self) -> &Self::Target {
104                &self.0
105            }
106        }
107
108        impl<T> DerefMut for $type {
109            fn deref_mut(&mut self) -> &mut Self::Target {
110                &mut self.0
111            }
112        }
113
114        impl<T> From<T> for $type {
115            fn from(value: T) -> $type {
116                $cons(value)
117            }
118        }
119    };
120}
121
122macro_rules! impl_serde {
123    ($type:ty, $constr:ident, $compress:expr, $validate:expr, $vecmod:ident) => {
124        #[cfg(feature = "serde")]
125        impl<T> ::serde::Serialize for $type
126        where
127            T: CanonicalSerialize,
128        {
129            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
130            where
131                S: ::serde::Serializer,
132            {
133                let mut buf = ark_std::vec![];
134                self.0
135                    .serialize_with_mode(&mut buf, $compress)
136                    .map_err(|e| ::serde::ser::Error::custom(e.to_string()))?;
137                serde_encoded_bytes::SliceLike::<serde_encoded_bytes::Base64>::serialize(
138                    &buf, serializer,
139                )
140            }
141        }
142
143        #[cfg(feature = "serde")]
144        impl<'de, T> ::serde::Deserialize<'de> for $type
145        where
146            T: CanonicalDeserialize,
147        {
148            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
149            where
150                D: ::serde::Deserializer<'de>,
151            {
152                let buf: ark_std::vec::Vec<u8> = <serde_encoded_bytes::SliceLike<
153                    serde_encoded_bytes::Base64,
154                >>::deserialize(deserializer)?;
155                let t = T::deserialize_with_mode(&buf[..], $compress, $validate)
156                    .map_err(|e| ::serde::de::Error::custom(e.to_string()))?;
157                Ok(Self(t))
158            }
159        }
160
161        #[cfg(feature = "serde_with")]
162        impl<T> serde_with::SerializeAs<T> for $type
163        where
164            T: CanonicalSerialize,
165        {
166            fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
167            where
168                S: ::serde::Serializer,
169            {
170                use ::serde::Serialize;
171                $constr(value).serialize(serializer)
172            }
173        }
174
175        #[cfg(feature = "serde_with")]
176        impl<'de, T> serde_with::DeserializeAs<'de, T> for $type
177        where
178            T: CanonicalDeserialize,
179        {
180            fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
181            where
182                D: ::serde::Deserializer<'de>,
183            {
184                use ::serde::Deserialize;
185                let val: Self = Self::deserialize(deserializer)?;
186                Ok(val.0)
187            }
188        }
189
190        #[cfg(feature = "serde")]
191        pub mod $vecmod {
192            use crate::{CanonicalDeserialize, CanonicalSerialize, CompressedChecked};
193            use ::serde::ser::SerializeSeq;
194            use ::serde::{Deserializer, Serializer};
195            use ark_std::fmt;
196            use ark_std::vec::Vec;
197
198            pub fn serialize<S, T>(
199                value: &impl AsRef<[T]>,
200                serializer: S,
201            ) -> Result<S::Ok, S::Error>
202            where
203                S: Serializer,
204                T: CanonicalSerialize,
205            {
206                let values = value.as_ref();
207                let mut seq = serializer.serialize_seq(Some(values.len()))?;
208                for val in values {
209                    seq.serialize_element(&CompressedChecked(val))?;
210                }
211                seq.end()
212            }
213
214            pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
215            where
216                D: Deserializer<'de>,
217                T: CanonicalDeserialize,
218            {
219                struct VecCanonicalVisitor<T> {
220                    accum: Vec<T>,
221                }
222                impl<'de, T> serde::de::Visitor<'de> for VecCanonicalVisitor<T>
223                where
224                    T: CanonicalDeserialize,
225                {
226                    type Value = Vec<T>;
227
228                    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
229                        write!(
230                            formatter,
231                            "a sequence of CompressedChecked<{}>",
232                            ark_std::any::type_name::<T>()
233                        )
234                    }
235
236                    fn visit_seq<A>(mut self, mut seq: A) -> Result<Self::Value, A::Error>
237                    where
238                        A: serde::de::SeqAccess<'de>,
239                    {
240                        while let Some(elt) = seq.next_element::<CompressedChecked<T>>()? {
241                            self.accum.push(elt.0);
242                        }
243                        Ok(self.accum)
244                    }
245                }
246                deserializer.deserialize_seq(VecCanonicalVisitor { accum: Vec::new() })
247            }
248        }
249    };
250}
251
252macro_rules! impl_canonical {
253    ($type:ty, $compress:expr, $validate:expr) => {
254        impl<T: CanonicalSerialize> CanonicalSerialize for $type {
255            fn serialize_with_mode<W: Write>(
256                &self,
257                writer: W,
258                _compress: Compress,
259            ) -> Result<(), SerializationError> {
260                match $compress {
261                    Compress::Yes => self.0.serialize_compressed(writer),
262                    Compress::No => self.0.serialize_uncompressed(writer),
263                }
264            }
265
266            fn serialized_size(&self, _compress: Compress) -> usize {
267                self.0.serialized_size($compress)
268            }
269        }
270
271        impl<T: Valid> Valid for $type {
272            fn check(&self) -> Result<(), SerializationError> {
273                self.0.check()
274            }
275        }
276
277        impl<T: CanonicalDeserialize> CanonicalDeserialize for $type {
278            fn deserialize_with_mode<R: Read>(
279                reader: R,
280                _compress: Compress,
281                _validate: Validate,
282            ) -> Result<Self, SerializationError> {
283                Ok(Self(T::deserialize_with_mode(
284                    reader, $compress, $validate,
285                )?))
286            }
287        }
288    };
289}
290
291impl_ops!(CompressedUnchecked<T>, CompressedUnchecked);
292impl_ops!(UncompressedUnchecked<T>, UncompressedUnchecked);
293impl_ops!(CompressedChecked<T>, CompressedChecked);
294impl_ops!(UncompressedChecked<T>, UncompressedChecked);
295
296impl_serde!(
297    CompressedUnchecked<T>,
298    CompressedUnchecked,
299    Compress::Yes,
300    Validate::No,
301    vec_compressed_unchecked
302);
303impl_serde!(
304    UncompressedUnchecked<T>,
305    UncompressedUnchecked,
306    Compress::No,
307    Validate::No,
308    vec_uncompressed_unchecked
309);
310impl_serde!(
311    CompressedChecked<T>,
312    CompressedChecked,
313    Compress::Yes,
314    Validate::Yes,
315    vec_compressed_checked
316);
317impl_serde!(
318    UncompressedChecked<T>,
319    UncompressedChecked,
320    Compress::No,
321    Validate::Yes,
322    vec_uncompressed_checked
323);
324
325impl_canonical!(CompressedUnchecked<T>, Compress::Yes, Validate::No);
326impl_canonical!(UncompressedUnchecked<T>, Compress::No, Validate::No);
327impl_canonical!(CompressedChecked<T>, Compress::Yes, Validate::Yes);
328impl_canonical!(UncompressedChecked<T>, Compress::No, Validate::Yes);