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