pythnet_sdk/wire/
ser.rs

1//! A module defining serde serialize for a simple Rust struct-like message format. The format will
2//! read Rust types exactly the size they are, and reads sequences by reading a u8 length followed
3//! by a count of the elements of the vector.
4//!
5//! TL;DR: How to Use
6//! ================================================================================
7//!
8//! ```rust,ignore
9//! #[derive(Serialize)]
10//! struct ExampleStruct {
11//!     a: (),
12//!     b: bool,
13//!     c: u8,
14//!     ...,
15//! }
16//!
17//! let mut buf = Vec::new();
18//! pythnet_sdk::ser::to_writer(&mut buf, &ExampleStruct { ... }).unwrap();
19//! let result = pythnet_sdk::ser::to_vec(&ExampleStruct { ... }).unwrap();
20//! ```
21//!
22//! A quick primer on `serde::Serialize`:
23//! ================================================================================
24//!
25//! Given some type `T`, the `serde::Serialize` derives an implementation with a `serialize` method
26//! that calls all the relevant `serialize_` calls defined in this file, so for example, given the
27//! following types:
28//!
29//! ```rust,ignore
30//! #[derive(Serialize)]
31//! enum ExampleEnum {
32//!    A,
33//!    B(u8),
34//!    C(u8, u8),
35//!    D { a: u8, b: u8 },
36//! }
37//!
38//! #[derive(Serialize)]
39//! struct ExampleStruct {
40//!    a: (),
41//!    b: bool,
42//!    c: u8,
43//!    d: &str,
44//!    e: ExampleEnum
45//! }
46//! ```
47//!
48//! The macro will expand into (a more complicated but equivalent) version of:
49//!
50//! ```rust,ignore
51//! impl serde::Serialize for ExampleEnum {
52//!     fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
53//!         match self {
54//!             ExampleEnum::A => serializer.serialize_unit_variant("ExampleEnum", 0, "A"),
55//!             ExampleEnum::B(v) => serializer.serialize_newtype_variant("ExampleEnum", 1, "B", v),
56//!             ExampleEnum::C(v0, v1) => serializer.serialize_tuple_variant("ExampleEnum", 2, "C", (v0, v1)),
57//!             ExampleEnum::D { a, b } => serializer.serialize_struct_variant("ExampleEnum", 3, "D", 2, "a", a, "b", b),
58//!         }
59//!     }
60//! }
61//!
62//! impl serde::Serialize for ExampleStruct {
63//!     fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
64//!         let mut state = serializer.serialize_struct("ExampleStruct", 5)?;
65//!         state.serialize_field("a", &self.a)?;
66//!         state.serialize_field("b", &self.b)?;
67//!         state.serialize_field("c", &self.c)?;
68//!         state.serialize_field("d", &self.d)?;
69//!         state.serialize_field("e", &self.e)?;
70//!         state.end()
71//!     }
72//! }
73//! ```
74//!
75//! Note that any parser can be passed in, which gives the serializer the ability to serialize to
76//! any format we desire as long as there is a `Serializer` implementation for it. With aggressive
77//! inlining, the compiler will be able to optimize away the intermediate state objects and calls
78//! to `serialize_field` and `serialize_*_variant` and the final result of our parser will have
79//! very close to equivalent performance to a hand written implementation.
80//!
81//! The Pyth Serialization Format
82//! ================================================================================
83//!
84//! Pyth has various data formats that are serialized in compact forms to make storing or passing
85//! cross-chain cheaper. So far all these formats follow a similar pattern and so this serializer
86//! is designed to be able to provide a canonical implementation for all of them.
87//!
88//!
89//! Format Spec:
90//! --------------------------------------------------------------------------------
91//!
92//! Integers:
93//!
94//! - `{u,i}8` are serialized as a single byte
95//! - `{u,i}16/32/64/128` are serialized as bytes specified by the parser endianness type param.
96//! - Custom {U,I}128/256 wrappers may be implemented later (similar to Borsh) for better support
97//!   in JS, debugging, logging, etc.
98//!
99//! Floats:
100//!
101//! - `f32/64/128` are not supported due to different chains having different float formats.
102//!
103//! Strings:
104//!
105//! - `&str` is serialized as a u8 length followed by the bytes of the string.
106//! - `String` is serialized as a u8 length followed by the bytes of the string.
107//!
108//! Sequences:
109//!
110//! - `Vec<T>` is serialized as a u8 length followed by the serialized elements of the vector.
111//! - `&[T]` is serialized as a u8 length followed by the serialized elements of the slice.
112//!
113//! Enums:
114//!
115//! - `enum` is serialized as a u8 variant index followed by the serialized variant data.
116//! - `Option<T>` is serialized as a u8 variant index followed by the serialized variant data.
117//!
118//! Structs:
119//!
120//! - `struct` is serialized as the serialized fields of the struct in order.
121//!
122//! Tuples:
123//!
124//! - `tuple` is serialized as the serialized elements of the tuple in order.
125//!
126//! Unit:
127//!
128//! - `()` is serialized as nothing.
129//!
130//!
131//! Example Usage
132//! --------------------------------------------------------------------------------
133//!
134//! ```rust,ignore
135//! fn example(data: &[u8]) {
136//!     let mut buf = Vec::new();
137//!     let mut cur = Cursor::new(&mut buf);
138//!     let mut des = Deserializer::new(&mut cur);
139//!     let mut result = des.deserialize::<ExampleStruct>(data).unwrap();
140//!     ...
141//! }
142//! ```
143
144use {
145    byteorder::{
146        ByteOrder,
147        WriteBytesExt,
148    },
149    serde::{
150        ser::{
151            SerializeMap,
152            SerializeSeq,
153            SerializeStruct,
154            SerializeStructVariant,
155            SerializeTuple,
156            SerializeTupleStruct,
157            SerializeTupleVariant,
158        },
159        Serialize,
160    },
161    std::{
162        fmt::Display,
163        io::Write,
164    },
165    thiserror::Error,
166};
167
168pub fn to_writer<T, W, B>(writer: W, value: &T) -> Result<(), SerializerError>
169where
170    T: Serialize,
171    W: Write,
172    B: ByteOrder,
173{
174    value.serialize(&mut Serializer::<_, B>::new(writer))?;
175    Ok(())
176}
177
178pub fn to_vec<T, B>(value: &T) -> Result<Vec<u8>, SerializerError>
179where
180    T: Serialize,
181    B: ByteOrder,
182{
183    let mut buf = Vec::new();
184    to_writer::<T, _, B>(&mut buf, value)?;
185    Ok(buf)
186}
187
188#[derive(Debug, Error)]
189pub enum SerializerError {
190    #[error("io error: {0}")]
191    Io(#[from] std::io::Error),
192
193    #[error("this type is not supported")]
194    Unsupported,
195
196    #[error("sequence too large ({0} elements), max supported is 255")]
197    SequenceTooLarge(usize),
198
199    #[error("sequence length must be known before serializing")]
200    SequenceLengthUnknown,
201
202    #[error("enum variant {0}::{1} cannot be parsed as `u8`: {2}")]
203    InvalidEnumVariant(&'static str, u32, &'static str),
204
205    #[error("message: {0}")]
206    Message(Box<str>),
207}
208
209/// A type for Pyth's common serialization format. Note that a ByteOrder type param is required as
210/// we serialize in both big and little endian depending on different use-cases.
211#[derive(Clone)]
212pub struct Serializer<W: Write, B: ByteOrder> {
213    writer:  W,
214    _endian: std::marker::PhantomData<B>,
215}
216
217impl serde::ser::Error for SerializerError {
218    fn custom<T: Display>(msg: T) -> Self {
219        SerializerError::Message(msg.to_string().into_boxed_str())
220    }
221}
222
223impl<W: Write, B: ByteOrder> Serializer<W, B> {
224    pub fn new(writer: W) -> Self {
225        Self {
226            writer,
227            _endian: std::marker::PhantomData,
228        }
229    }
230}
231
232impl<'a, W: Write, B: ByteOrder> serde::Serializer for &'a mut Serializer<W, B> {
233    type Ok = ();
234    type Error = SerializerError;
235
236    // Serde uses different types for different parse targets to allow for different
237    // implementations. We only support one target, so we can set all these to `Self`
238    // and implement those traits on the same type.
239    type SerializeSeq = Self;
240    type SerializeTuple = Self;
241    type SerializeTupleStruct = Self;
242    type SerializeTupleVariant = Self;
243    type SerializeMap = Self;
244    type SerializeStruct = Self;
245    type SerializeStructVariant = Self;
246
247    #[inline]
248    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
249        self.writer
250            .write_all(&[v as u8])
251            .map_err(SerializerError::from)
252    }
253
254    #[inline]
255    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
256        self.writer
257            .write_all(&[v as u8])
258            .map_err(SerializerError::from)
259    }
260
261    #[inline]
262    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
263        self.writer.write_i16::<B>(v).map_err(SerializerError::from)
264    }
265
266    #[inline]
267    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
268        self.writer.write_i32::<B>(v).map_err(SerializerError::from)
269    }
270
271    #[inline]
272    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
273        self.writer.write_i64::<B>(v).map_err(SerializerError::from)
274    }
275
276    #[inline]
277    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
278        self.writer
279            .write_i128::<B>(v)
280            .map_err(SerializerError::from)
281    }
282
283    #[inline]
284    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
285        self.writer.write_all(&[v]).map_err(SerializerError::from)
286    }
287
288    #[inline]
289    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
290        self.writer.write_u16::<B>(v).map_err(SerializerError::from)
291    }
292
293    #[inline]
294    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
295        self.writer.write_u32::<B>(v).map_err(SerializerError::from)
296    }
297
298    #[inline]
299    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
300        self.writer.write_u64::<B>(v).map_err(SerializerError::from)
301    }
302
303    #[inline]
304    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
305        self.writer
306            .write_u128::<B>(v)
307            .map_err(SerializerError::from)
308    }
309
310    #[inline]
311    fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
312        Err(SerializerError::Unsupported)
313    }
314
315    #[inline]
316    fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
317        Err(SerializerError::Unsupported)
318    }
319
320    #[inline]
321    fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
322        Err(SerializerError::Unsupported)
323    }
324
325    #[inline]
326    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
327        let len = u8::try_from(v.len()).map_err(|_| SerializerError::SequenceTooLarge(v.len()))?;
328        self.writer.write_all(&[len])?;
329        self.writer
330            .write_all(v.as_bytes())
331            .map_err(SerializerError::from)
332    }
333
334    #[inline]
335    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
336        let len = u8::try_from(v.len()).map_err(|_| SerializerError::SequenceTooLarge(v.len()))?;
337        self.writer.write_all(&[len])?;
338        self.writer.write_all(v).map_err(SerializerError::from)
339    }
340
341    #[inline]
342    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
343        Err(SerializerError::Unsupported)
344    }
345
346    #[inline]
347    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
348        value.serialize(self)
349    }
350
351    #[inline]
352    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
353        Ok(())
354    }
355
356    #[inline]
357    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
358        Ok(())
359    }
360
361    #[inline]
362    fn serialize_unit_variant(
363        self,
364        name: &'static str,
365        variant_index: u32,
366        variant: &'static str,
367    ) -> Result<Self::Ok, Self::Error> {
368        let variant: u8 = variant_index
369            .try_into()
370            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
371
372        self.writer
373            .write_all(&[variant])
374            .map_err(SerializerError::from)
375    }
376
377    #[inline]
378    fn serialize_newtype_struct<T: ?Sized + Serialize>(
379        self,
380        _name: &'static str,
381        value: &T,
382    ) -> Result<Self::Ok, Self::Error> {
383        value.serialize(self)
384    }
385
386    #[inline]
387    fn serialize_newtype_variant<T: ?Sized + Serialize>(
388        self,
389        name: &'static str,
390        variant_index: u32,
391        variant: &'static str,
392        value: &T,
393    ) -> Result<Self::Ok, Self::Error> {
394        let variant: u8 = variant_index
395            .try_into()
396            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
397
398        self.writer.write_all(&[variant])?;
399        value.serialize(self)
400    }
401
402    /// We use the fact that len can be None here to optionally not prefix a sequence when we
403    /// serialize. This allows us to disable length prefixing optionally when writing serializers
404    /// by hand. See `PrefixlessVec` for an example.
405    #[inline]
406    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
407        if let Some(len) = len {
408            let len = u8::try_from(len).map_err(|_| SerializerError::SequenceTooLarge(len))?;
409            self.writer.write_all(&[len])?;
410        }
411
412        Ok(self)
413    }
414
415    #[inline]
416    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
417        Ok(self)
418    }
419
420    #[inline]
421    fn serialize_tuple_struct(
422        self,
423        _name: &'static str,
424        _len: usize,
425    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
426        Ok(self)
427    }
428
429    #[inline]
430    fn serialize_tuple_variant(
431        self,
432        name: &'static str,
433        variant_index: u32,
434        variant: &'static str,
435        _len: usize,
436    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
437        let variant: u8 = variant_index
438            .try_into()
439            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
440
441        self.writer.write_all(&[variant])?;
442        Ok(self)
443    }
444
445    #[inline]
446    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
447        let len = len
448            .ok_or(SerializerError::SequenceLengthUnknown)
449            .and_then(|len| {
450                u8::try_from(len).map_err(|_| SerializerError::SequenceTooLarge(len))
451            })?;
452
453        self.writer.write_all(&[len])?;
454        Ok(self)
455    }
456
457    #[inline]
458    fn serialize_struct(
459        self,
460        _name: &'static str,
461        _len: usize,
462    ) -> Result<Self::SerializeStruct, Self::Error> {
463        Ok(self)
464    }
465
466    #[inline]
467    fn serialize_struct_variant(
468        self,
469        name: &'static str,
470        variant_index: u32,
471        variant: &'static str,
472        _len: usize,
473    ) -> Result<Self::SerializeStructVariant, Self::Error> {
474        let variant: u8 = variant_index
475            .try_into()
476            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
477
478        self.writer.write_all(&[variant])?;
479        Ok(self)
480    }
481
482    fn is_human_readable(&self) -> bool {
483        false
484    }
485
486    fn collect_str<T: ?Sized + Display>(self, value: &T) -> Result<Self::Ok, Self::Error> {
487        self.serialize_str(&value.to_string())
488    }
489}
490
491impl<'a, W: Write, B: ByteOrder> SerializeSeq for &'a mut Serializer<W, B> {
492    type Ok = ();
493    type Error = SerializerError;
494
495    #[inline]
496    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
497        value.serialize(&mut **self)
498    }
499
500    fn end(self) -> Result<Self::Ok, Self::Error> {
501        Ok(())
502    }
503}
504
505impl<'a, W: Write, B: ByteOrder> SerializeTuple for &'a mut Serializer<W, B> {
506    type Ok = ();
507    type Error = SerializerError;
508
509    #[inline]
510    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
511        value.serialize(&mut **self)
512    }
513
514    fn end(self) -> Result<Self::Ok, Self::Error> {
515        Ok(())
516    }
517}
518
519impl<'a, W: Write, B: ByteOrder> SerializeTupleStruct for &'a mut Serializer<W, B> {
520    type Ok = ();
521    type Error = SerializerError;
522
523    #[inline]
524    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
525        value.serialize(&mut **self)
526    }
527
528    fn end(self) -> Result<Self::Ok, Self::Error> {
529        Ok(())
530    }
531}
532
533impl<'a, W: Write, B: ByteOrder> SerializeTupleVariant for &'a mut Serializer<W, B> {
534    type Ok = ();
535    type Error = SerializerError;
536
537    #[inline]
538    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
539        value.serialize(&mut **self)
540    }
541
542    fn end(self) -> Result<Self::Ok, Self::Error> {
543        Ok(())
544    }
545}
546
547impl<'a, W: Write, B: ByteOrder> SerializeMap for &'a mut Serializer<W, B> {
548    type Ok = ();
549    type Error = SerializerError;
550
551    #[inline]
552    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Self::Error> {
553        key.serialize(&mut **self)
554    }
555
556    #[inline]
557    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
558        value.serialize(&mut **self)
559    }
560
561    fn end(self) -> Result<Self::Ok, Self::Error> {
562        Ok(())
563    }
564}
565
566impl<'a, W: Write, B: ByteOrder> SerializeStruct for &'a mut Serializer<W, B> {
567    type Ok = ();
568    type Error = SerializerError;
569
570    #[inline]
571    fn serialize_field<T: ?Sized + Serialize>(
572        &mut self,
573        _key: &'static str,
574        value: &T,
575    ) -> Result<(), Self::Error> {
576        value.serialize(&mut **self)
577    }
578
579    fn end(self) -> Result<Self::Ok, Self::Error> {
580        Ok(())
581    }
582}
583
584impl<'a, W: Write, B: ByteOrder> SerializeStructVariant for &'a mut Serializer<W, B> {
585    type Ok = ();
586    type Error = SerializerError;
587
588    #[inline]
589    fn serialize_field<T: ?Sized + Serialize>(
590        &mut self,
591        _key: &'static str,
592        value: &T,
593    ) -> Result<(), Self::Error> {
594        value.serialize(&mut **self)
595    }
596
597    fn end(self) -> Result<Self::Ok, Self::Error> {
598        Ok(())
599    }
600}