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::{ByteOrder, WriteBytesExt},
146    serde::{
147        ser::{
148            SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
149            SerializeTupleStruct, SerializeTupleVariant,
150        },
151        Serialize,
152    },
153    std::{fmt::Display, io::Write},
154    thiserror::Error,
155};
156
157pub fn to_writer<T, W, B>(writer: W, value: &T) -> Result<(), SerializerError>
158where
159    T: Serialize,
160    W: Write,
161    B: ByteOrder,
162{
163    value.serialize(&mut Serializer::<_, B>::new(writer))?;
164    Ok(())
165}
166
167pub fn to_vec<T, B>(value: &T) -> Result<Vec<u8>, SerializerError>
168where
169    T: Serialize,
170    B: ByteOrder,
171{
172    let mut buf = Vec::new();
173    to_writer::<T, _, B>(&mut buf, value)?;
174    Ok(buf)
175}
176
177#[derive(Debug, Error)]
178pub enum SerializerError {
179    #[error("io error: {0}")]
180    Io(#[from] std::io::Error),
181
182    #[error("this type is not supported")]
183    Unsupported,
184
185    #[error("sequence too large ({0} elements), max supported is 255")]
186    SequenceTooLarge(usize),
187
188    #[error("sequence length must be known before serializing")]
189    SequenceLengthUnknown,
190
191    #[error("enum variant {0}::{1} cannot be parsed as `u8`: {2}")]
192    InvalidEnumVariant(&'static str, u32, &'static str),
193
194    #[error("message: {0}")]
195    Message(Box<str>),
196}
197
198/// A type for Pyth's common serialization format. Note that a ByteOrder type param is required as
199/// we serialize in both big and little endian depending on different use-cases.
200#[derive(Clone)]
201pub struct Serializer<W: Write, B: ByteOrder> {
202    writer: W,
203    _endian: std::marker::PhantomData<B>,
204}
205
206impl serde::ser::Error for SerializerError {
207    fn custom<T: Display>(msg: T) -> Self {
208        SerializerError::Message(msg.to_string().into_boxed_str())
209    }
210}
211
212impl<W: Write, B: ByteOrder> Serializer<W, B> {
213    pub fn new(writer: W) -> Self {
214        Self {
215            writer,
216            _endian: std::marker::PhantomData,
217        }
218    }
219}
220
221impl<'a, W: Write, B: ByteOrder> serde::Serializer for &'a mut Serializer<W, B> {
222    type Ok = ();
223    type Error = SerializerError;
224
225    // Serde uses different types for different parse targets to allow for different
226    // implementations. We only support one target, so we can set all these to `Self`
227    // and implement those traits on the same type.
228    type SerializeSeq = Self;
229    type SerializeTuple = Self;
230    type SerializeTupleStruct = Self;
231    type SerializeTupleVariant = Self;
232    type SerializeMap = Self;
233    type SerializeStruct = Self;
234    type SerializeStructVariant = Self;
235
236    #[inline]
237    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
238        self.writer
239            .write_all(&[v as u8])
240            .map_err(SerializerError::from)
241    }
242
243    #[inline]
244    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
245        self.writer
246            .write_all(&[v as u8])
247            .map_err(SerializerError::from)
248    }
249
250    #[inline]
251    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
252        self.writer.write_i16::<B>(v).map_err(SerializerError::from)
253    }
254
255    #[inline]
256    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
257        self.writer.write_i32::<B>(v).map_err(SerializerError::from)
258    }
259
260    #[inline]
261    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
262        self.writer.write_i64::<B>(v).map_err(SerializerError::from)
263    }
264
265    #[inline]
266    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
267        self.writer
268            .write_i128::<B>(v)
269            .map_err(SerializerError::from)
270    }
271
272    #[inline]
273    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
274        self.writer.write_all(&[v]).map_err(SerializerError::from)
275    }
276
277    #[inline]
278    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
279        self.writer.write_u16::<B>(v).map_err(SerializerError::from)
280    }
281
282    #[inline]
283    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
284        self.writer.write_u32::<B>(v).map_err(SerializerError::from)
285    }
286
287    #[inline]
288    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
289        self.writer.write_u64::<B>(v).map_err(SerializerError::from)
290    }
291
292    #[inline]
293    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
294        self.writer
295            .write_u128::<B>(v)
296            .map_err(SerializerError::from)
297    }
298
299    #[inline]
300    fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
301        Err(SerializerError::Unsupported)
302    }
303
304    #[inline]
305    fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
306        Err(SerializerError::Unsupported)
307    }
308
309    #[inline]
310    fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
311        Err(SerializerError::Unsupported)
312    }
313
314    #[inline]
315    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
316        let len = u8::try_from(v.len()).map_err(|_| SerializerError::SequenceTooLarge(v.len()))?;
317        self.writer.write_all(&[len])?;
318        self.writer
319            .write_all(v.as_bytes())
320            .map_err(SerializerError::from)
321    }
322
323    #[inline]
324    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
325        let len = u8::try_from(v.len()).map_err(|_| SerializerError::SequenceTooLarge(v.len()))?;
326        self.writer.write_all(&[len])?;
327        self.writer.write_all(v).map_err(SerializerError::from)
328    }
329
330    #[inline]
331    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
332        Err(SerializerError::Unsupported)
333    }
334
335    #[inline]
336    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
337        value.serialize(self)
338    }
339
340    #[inline]
341    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
342        Ok(())
343    }
344
345    #[inline]
346    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
347        Ok(())
348    }
349
350    #[inline]
351    fn serialize_unit_variant(
352        self,
353        name: &'static str,
354        variant_index: u32,
355        variant: &'static str,
356    ) -> Result<Self::Ok, Self::Error> {
357        let variant: u8 = variant_index
358            .try_into()
359            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
360
361        self.writer
362            .write_all(&[variant])
363            .map_err(SerializerError::from)
364    }
365
366    #[inline]
367    fn serialize_newtype_struct<T: ?Sized + Serialize>(
368        self,
369        _name: &'static str,
370        value: &T,
371    ) -> Result<Self::Ok, Self::Error> {
372        value.serialize(self)
373    }
374
375    #[inline]
376    fn serialize_newtype_variant<T: ?Sized + Serialize>(
377        self,
378        name: &'static str,
379        variant_index: u32,
380        variant: &'static str,
381        value: &T,
382    ) -> Result<Self::Ok, Self::Error> {
383        let variant: u8 = variant_index
384            .try_into()
385            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
386
387        self.writer.write_all(&[variant])?;
388        value.serialize(self)
389    }
390
391    /// We use the fact that len can be None here to optionally not prefix a sequence when we
392    /// serialize. This allows us to disable length prefixing optionally when writing serializers
393    /// by hand. See `PrefixlessVec` for an example.
394    #[inline]
395    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
396        if let Some(len) = len {
397            let len = u8::try_from(len).map_err(|_| SerializerError::SequenceTooLarge(len))?;
398            self.writer.write_all(&[len])?;
399        }
400
401        Ok(self)
402    }
403
404    #[inline]
405    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
406        Ok(self)
407    }
408
409    #[inline]
410    fn serialize_tuple_struct(
411        self,
412        _name: &'static str,
413        _len: usize,
414    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
415        Ok(self)
416    }
417
418    #[inline]
419    fn serialize_tuple_variant(
420        self,
421        name: &'static str,
422        variant_index: u32,
423        variant: &'static str,
424        _len: usize,
425    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
426        let variant: u8 = variant_index
427            .try_into()
428            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
429
430        self.writer.write_all(&[variant])?;
431        Ok(self)
432    }
433
434    #[inline]
435    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
436        let len = len
437            .ok_or(SerializerError::SequenceLengthUnknown)
438            .and_then(|len| {
439                u8::try_from(len).map_err(|_| SerializerError::SequenceTooLarge(len))
440            })?;
441
442        self.writer.write_all(&[len])?;
443        Ok(self)
444    }
445
446    #[inline]
447    fn serialize_struct(
448        self,
449        _name: &'static str,
450        _len: usize,
451    ) -> Result<Self::SerializeStruct, Self::Error> {
452        Ok(self)
453    }
454
455    #[inline]
456    fn serialize_struct_variant(
457        self,
458        name: &'static str,
459        variant_index: u32,
460        variant: &'static str,
461        _len: usize,
462    ) -> Result<Self::SerializeStructVariant, Self::Error> {
463        let variant: u8 = variant_index
464            .try_into()
465            .map_err(|_| SerializerError::InvalidEnumVariant(name, variant_index, variant))?;
466
467        self.writer.write_all(&[variant])?;
468        Ok(self)
469    }
470
471    fn is_human_readable(&self) -> bool {
472        false
473    }
474
475    fn collect_str<T: ?Sized + Display>(self, value: &T) -> Result<Self::Ok, Self::Error> {
476        self.serialize_str(&value.to_string())
477    }
478}
479
480impl<'a, W: Write, B: ByteOrder> SerializeSeq for &'a mut Serializer<W, B> {
481    type Ok = ();
482    type Error = SerializerError;
483
484    #[inline]
485    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
486        value.serialize(&mut **self)
487    }
488
489    fn end(self) -> Result<Self::Ok, Self::Error> {
490        Ok(())
491    }
492}
493
494impl<'a, W: Write, B: ByteOrder> SerializeTuple for &'a mut Serializer<W, B> {
495    type Ok = ();
496    type Error = SerializerError;
497
498    #[inline]
499    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
500        value.serialize(&mut **self)
501    }
502
503    fn end(self) -> Result<Self::Ok, Self::Error> {
504        Ok(())
505    }
506}
507
508impl<'a, W: Write, B: ByteOrder> SerializeTupleStruct for &'a mut Serializer<W, B> {
509    type Ok = ();
510    type Error = SerializerError;
511
512    #[inline]
513    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
514        value.serialize(&mut **self)
515    }
516
517    fn end(self) -> Result<Self::Ok, Self::Error> {
518        Ok(())
519    }
520}
521
522impl<'a, W: Write, B: ByteOrder> SerializeTupleVariant for &'a mut Serializer<W, B> {
523    type Ok = ();
524    type Error = SerializerError;
525
526    #[inline]
527    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
528        value.serialize(&mut **self)
529    }
530
531    fn end(self) -> Result<Self::Ok, Self::Error> {
532        Ok(())
533    }
534}
535
536impl<'a, W: Write, B: ByteOrder> SerializeMap for &'a mut Serializer<W, B> {
537    type Ok = ();
538    type Error = SerializerError;
539
540    #[inline]
541    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Self::Error> {
542        key.serialize(&mut **self)
543    }
544
545    #[inline]
546    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
547        value.serialize(&mut **self)
548    }
549
550    fn end(self) -> Result<Self::Ok, Self::Error> {
551        Ok(())
552    }
553}
554
555impl<'a, W: Write, B: ByteOrder> SerializeStruct for &'a mut Serializer<W, B> {
556    type Ok = ();
557    type Error = SerializerError;
558
559    #[inline]
560    fn serialize_field<T: ?Sized + Serialize>(
561        &mut self,
562        _key: &'static str,
563        value: &T,
564    ) -> Result<(), Self::Error> {
565        value.serialize(&mut **self)
566    }
567
568    fn end(self) -> Result<Self::Ok, Self::Error> {
569        Ok(())
570    }
571}
572
573impl<'a, W: Write, B: ByteOrder> SerializeStructVariant for &'a mut Serializer<W, B> {
574    type Ok = ();
575    type Error = SerializerError;
576
577    #[inline]
578    fn serialize_field<T: ?Sized + Serialize>(
579        &mut self,
580        _key: &'static str,
581        value: &T,
582    ) -> Result<(), Self::Error> {
583        value.serialize(&mut **self)
584    }
585
586    fn end(self) -> Result<Self::Ok, Self::Error> {
587        Ok(())
588    }
589}