Skip to main content

workflow_serializer/
serializer.rs

1use crate::payload::{de, ser};
2use crate::{load, store};
3use borsh::{BorshDeserialize, BorshSerialize};
4use serde::{Deserialize, Serialize};
5use std::fmt::Debug;
6use std::ops::Deref;
7
8/// Blanket marker trait for any [`Serializer`] that is also `Send` and `Sync`.
9pub trait SerializerT: Serializer + Send + Sync {}
10impl<T> SerializerT for T where T: Serializer + Send + Sync {}
11
12/// Blanket marker trait for any [`Deserializer`] that is also `Send` and `Sync`.
13pub trait DeserializerT: Deserializer + Send + Sync {}
14impl<T> DeserializerT for T where T: Deserializer + Send + Sync {}
15
16/// Wrapper that routes Borsh serialization of the inner value through the
17/// [`Serializer`]/[`Deserializer`] traits, enabling custom metadata while
18/// preventing direct Borsh serialization of the wrapped type.
19#[derive(Debug, Serialize, Deserialize)]
20#[repr(transparent)]
21pub struct Serializable<T>(pub T)
22where
23    T: SerializerT + DeserializerT;
24
25impl<T> Serializable<T>
26where
27    T: SerializerT + DeserializerT,
28{
29    /// Consumes the wrapper, returning the inner value.
30    pub fn into_inner(self) -> T {
31        self.0
32    }
33}
34
35impl<T> From<T> for Serializable<T>
36where
37    T: SerializerT + DeserializerT,
38{
39    fn from(t: T) -> Self {
40        Serializable(t)
41    }
42}
43
44impl<T> Deref for Serializable<T>
45where
46    T: SerializerT + DeserializerT,
47{
48    type Target = T;
49
50    fn deref(&self) -> &Self::Target {
51        &self.0
52    }
53}
54
55impl<T> AsRef<T> for Serializable<T>
56where
57    T: SerializerT + DeserializerT,
58{
59    fn as_ref(&self) -> &T {
60        &self.0
61    }
62}
63
64impl<T> BorshSerialize for Serializable<T>
65where
66    T: SerializerT + DeserializerT,
67{
68    fn serialize<W: std::io::Write>(&self, target: &mut W) -> std::io::Result<()> {
69        ser::Payload(&self.0).serialize(target)?;
70        Ok(())
71    }
72}
73
74impl<T> BorshDeserialize for Serializable<T>
75where
76    T: SerializerT + DeserializerT,
77{
78    fn deserialize_reader<R: borsh::io::Read>(source: &mut R) -> std::io::Result<Self> {
79        let t = de::Payload::<T>::deserialize(source)?;
80        Ok(Serializable(t.into_inner()))
81    }
82}
83
84/// `Serializer` is a trait that allows for data serialization and deserialization
85/// similar to Borsh, but via a separate trait. This allows for serialization
86/// of additional metadata while using underlying Borsh primitives. For example:
87/// a struct can implement both Borsh and Serializer traits where Serializer
88/// can store custom metadata (e.g. struct version) and then store the struct
89/// using Borsh.  Both [`Serializer`] and Borsh are almost identical, where
90/// [`Serializer`] is meant to signal intent for custom serialization.
91/// [`Serializer`] is a complimentary trait for [`Serializable`] struct
92/// and can be used to prevent direct Borsh serialization of a struct.
93pub trait Serializer: Sized {
94    /// Writes the serialized representation of `self` to the given writer.
95    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()>;
96
97    /// Serializes `self` into a newly allocated byte vector.
98    fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
99        let mut buf = Vec::new();
100        self.serialize(&mut buf)?;
101        Ok(buf)
102    }
103}
104
105/// Counterpart to [`Serializer`] that reconstructs a value from its custom
106/// serialized representation, complementing the [`Serializable`] wrapper.
107pub trait Deserializer: Sized {
108    /// Reads and reconstructs a value of `Self` from the given reader.
109    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self>;
110
111    /// Reconstructs a value of `Self` from a byte slice.
112    fn try_from_slice(slice: &[u8]) -> std::io::Result<Self> {
113        let mut buf = slice;
114        Self::deserialize(&mut buf)
115    }
116}
117
118type ResultStatusTag = u8;
119const RESULT_OK: ResultStatusTag = 0;
120const RESULT_ERR: ResultStatusTag = 1;
121
122impl<T, E> Serializer for Result<T, E>
123where
124    T: Serializer + 'static,
125    E: std::fmt::Display + BorshSerialize + 'static,
126{
127    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
128        match self {
129            Ok(t) => {
130                store!(ResultStatusTag, &RESULT_OK, writer)?;
131                ser::Payload(t).serialize(writer)?;
132            }
133            Err(e) => {
134                store!(ResultStatusTag, &RESULT_ERR, writer)?;
135                store!(E, e, writer)?;
136            }
137        }
138
139        Ok(())
140    }
141}
142
143impl<T, E> Deserializer for Result<T, E>
144where
145    T: Deserializer + 'static,
146    E: std::fmt::Display + BorshDeserialize + 'static,
147{
148    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
149        let tag = load!(ResultStatusTag, reader)?;
150        match tag {
151            RESULT_OK => {
152                let t = de::Payload::<T>::deserialize(reader)?;
153                Ok(Ok(t.into_inner()))
154            }
155            RESULT_ERR => {
156                let e = E::deserialize_reader(reader)?;
157                Ok(Err(e))
158            }
159            _ => Err(std::io::Error::new(
160                std::io::ErrorKind::InvalidData,
161                "invalid Serializer Result tag",
162            )),
163        }
164    }
165}
166
167type OptionStatusTag = u8;
168const OPTION_SOME: OptionStatusTag = 1;
169const OPTION_NONE: OptionStatusTag = 0;
170
171impl<T> Serializer for Option<T>
172where
173    T: Serializer + 'static,
174{
175    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
176        match self {
177            Some(t) => {
178                store!(OptionStatusTag, &OPTION_SOME, writer)?;
179                ser::Payload(t).serialize(writer)?;
180            }
181            None => {
182                store!(OptionStatusTag, &OPTION_NONE, writer)?;
183            }
184        }
185
186        Ok(())
187    }
188}
189
190impl<T> Deserializer for Option<T>
191where
192    T: Deserializer + 'static,
193{
194    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
195        let tag = load!(OptionStatusTag, reader)?;
196        match tag {
197            OPTION_SOME => {
198                let t = de::Payload::<T>::deserialize(reader)?;
199                Ok(Some(t.into_inner()))
200            }
201            OPTION_NONE => Ok(None),
202            _ => Err(std::io::Error::new(
203                std::io::ErrorKind::InvalidData,
204                "invalid Serializer Option tag",
205            )),
206        }
207    }
208}
209
210impl Serializer for String {
211    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
212        store!(String, self, writer)?;
213        Ok(())
214    }
215}
216
217impl Deserializer for String {
218    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
219        Ok(load!(String, reader)?)
220    }
221}
222
223impl<V> Serializer for Vec<V>
224where
225    V: Serializer,
226{
227    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
228        store!(u32, &(self.len() as u32), writer)?;
229
230        for item in self.iter() {
231            ser::Payload(item).serialize(writer)?;
232        }
233
234        Ok(())
235    }
236}
237
238impl<V> Deserializer for Vec<V>
239where
240    V: Deserializer,
241{
242    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
243        let len: u32 = load!(u32, reader)?;
244        let mut vec = Vec::with_capacity(len as usize);
245
246        for _ in 0..len {
247            let item = de::Payload::<V>::deserialize(reader)?;
248            vec.push(item.into_inner());
249        }
250
251        Ok(vec)
252    }
253}
254
255impl<K, V> Serializer for std::collections::HashMap<K, V>
256where
257    K: Serializer + std::hash::Hash + Eq,
258    V: Serializer,
259{
260    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
261        store!(u32, &(self.len() as u32), writer)?;
262
263        for (k, v) in self.iter() {
264            k.serialize(writer)?;
265            ser::Payload(v).serialize(writer)?;
266        }
267
268        Ok(())
269    }
270}
271
272impl<K, V> Deserializer for std::collections::HashMap<K, V>
273where
274    K: Deserializer + std::hash::Hash + Eq,
275    V: Deserializer,
276{
277    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
278        let len: u32 = load!(u32, reader)?;
279        let mut map = std::collections::HashMap::new();
280
281        for _ in 0..len {
282            let k = K::deserialize(reader)?;
283            let v = de::Payload::<V>::deserialize(reader)?;
284            map.insert(k, v.into_inner());
285        }
286
287        Ok(map)
288    }
289}
290
291impl<T> Serializer for std::collections::HashSet<T>
292where
293    T: Serializer + Send + Sync + std::hash::Hash + Eq,
294{
295    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
296        store!(u32, &(self.len() as u32), writer)?;
297
298        for item in self.iter() {
299            ser::Payload(item).serialize(writer)?;
300        }
301
302        Ok(())
303    }
304}
305
306impl<T> Deserializer for std::collections::HashSet<T>
307where
308    T: Deserializer + Send + Sync + std::hash::Hash + Eq,
309{
310    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
311        let len: u32 = load!(u32, reader)?;
312        let mut set = std::collections::HashSet::new();
313
314        for _ in 0..len {
315            let item = de::Payload::<T>::deserialize(reader)?;
316            set.insert(item.into_inner());
317        }
318
319        Ok(set)
320    }
321}
322
323impl<K, V> Serializer for ahash::AHashMap<K, V>
324where
325    K: Serializer + Send + Sync + std::hash::Hash + Eq,
326    V: Serializer + Send + Sync,
327{
328    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
329        store!(u32, &(self.len() as u32), writer)?;
330
331        for (k, v) in self.iter() {
332            k.serialize(writer)?;
333            ser::Payload(v).serialize(writer)?;
334        }
335
336        Ok(())
337    }
338}
339
340impl<K, V> Deserializer for ahash::AHashMap<K, V>
341where
342    K: Deserializer + Send + Sync + std::hash::Hash + Eq,
343    V: Deserializer + Send + Sync,
344{
345    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
346        let len: u32 = load!(u32, reader)?;
347        let mut map = ahash::AHashMap::new();
348
349        for _ in 0..len {
350            let k = K::deserialize(reader)?;
351            let v = de::Payload::<V>::deserialize(reader)?;
352            map.insert(k, v.into_inner());
353        }
354
355        Ok(map)
356    }
357}
358
359impl<T> Serializer for ahash::AHashSet<T>
360where
361    T: Serializer + std::hash::Hash + Eq,
362{
363    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
364        store!(u32, &(self.len() as u32), writer)?;
365
366        for item in self.iter() {
367            ser::Payload(item).serialize(writer)?;
368        }
369
370        Ok(())
371    }
372}
373
374impl<T> Deserializer for ahash::AHashSet<T>
375where
376    T: Deserializer + std::hash::Hash + Eq,
377{
378    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
379        let len: u32 = load!(u32, reader)?;
380        let mut set = ahash::AHashSet::new();
381
382        for _ in 0..len {
383            let item = de::Payload::<T>::deserialize(reader)?;
384            set.insert(item.into_inner());
385        }
386
387        Ok(set)
388    }
389}
390
391impl<K, V> Serializer for std::collections::BTreeMap<K, V>
392where
393    K: Serializer + Ord,
394    V: Serializer,
395{
396    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
397        store!(u32, &(self.len() as u32), writer)?;
398
399        for (k, v) in self.iter() {
400            k.serialize(writer)?;
401            ser::Payload(v).serialize(writer)?;
402        }
403
404        Ok(())
405    }
406}
407
408impl<K, V> Deserializer for std::collections::BTreeMap<K, V>
409where
410    K: Deserializer + Ord,
411    V: Deserializer,
412{
413    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
414        let len: u32 = load!(u32, reader)?;
415        let mut map = std::collections::BTreeMap::new();
416
417        for _ in 0..len {
418            let k = K::deserialize(reader)?;
419            let v = de::Payload::<V>::deserialize(reader)?;
420            map.insert(k, v.into_inner());
421        }
422
423        Ok(map)
424    }
425}
426
427impl<T> Serializer for std::collections::BTreeSet<T>
428where
429    T: Serializer + Ord,
430{
431    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
432        store!(u32, &(self.len() as u32), writer)?;
433
434        for item in self.iter() {
435            ser::Payload(item).serialize(writer)?;
436        }
437
438        Ok(())
439    }
440}
441
442impl<T> Deserializer for std::collections::BTreeSet<T>
443where
444    T: Deserializer + Ord,
445{
446    fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
447        let len: u32 = load!(u32, reader)?;
448        let mut set = std::collections::BTreeSet::new();
449
450        for _ in 0..len {
451            let item = de::Payload::<T>::deserialize(reader)?;
452            set.insert(item.into_inner());
453        }
454
455        Ok(set)
456    }
457}