pack_io/traits.rs
1//! The [`Serialize`] and [`Deserialize`] traits.
2//!
3//! These are the seam between a Rust value and its wire-format bytes. They
4//! are generic over the [`Encode`] / [`Decode`] behaviour traits, so a single
5//! `impl Serialize` works through both the in-memory [`crate::Encoder`] and
6//! the streaming [`crate::IoEncoder`].
7//!
8//! The built-in primitive and collection implementations live in
9//! [`crate::impls`]. User-defined types implement these traits directly today;
10//! the `derive` macro (lands in `0.4`) writes a sound implementation
11//! automatically.
12
13use crate::codec::{Decode, Encode};
14use crate::error::Result;
15
16/// Types that know how to write themselves into any [`Encode`] sink.
17///
18/// The contract is: `serialize` appends the type's wire-format bytes to the
19/// encoder. It does **not** clear the encoder first — encoders are
20/// stream-shaped, and may already hold bytes from prior writes.
21///
22/// Implementors MUST be deterministic: for any two equal values `a` and `b`
23/// (in the type's `Eq` / `PartialEq` sense, or its semantic equivalent for
24/// types like `f64`), the bytes appended by `a.serialize(&mut enc)` MUST
25/// equal the bytes appended by `b.serialize(&mut enc)`.
26///
27/// # Examples
28///
29/// ```
30/// use pack_io::{Encode, Encoder, Result, Serialize};
31///
32/// struct Point { x: i32, y: i32 }
33///
34/// impl Serialize for Point {
35/// fn serialize<E: Encode + ?Sized>(&self, enc: &mut E) -> Result<()> {
36/// self.x.serialize(enc)?;
37/// self.y.serialize(enc)
38/// }
39/// }
40///
41/// let mut enc = Encoder::new();
42/// Point { x: 3, y: -7 }.serialize(&mut enc).unwrap();
43/// assert!(!enc.as_bytes().is_empty());
44/// ```
45pub trait Serialize {
46 /// Append the encoded bytes of `self` to `encoder`.
47 ///
48 /// # Errors
49 ///
50 /// Primitive impls in this crate are infallible on the in-memory
51 /// [`crate::Encoder`]. Streaming encoders (`IoEncoder<W>`) may surface
52 /// a [`crate::SerialError`] when the underlying `Write` errors. User
53 /// impls may also surface custom errors via [`crate::SerialError`].
54 fn serialize<E: Encode + ?Sized>(&self, encoder: &mut E) -> Result<()>;
55}
56
57/// Types that know how to read themselves from any [`Decode`] source.
58///
59/// The contract is: `deserialize` consumes exactly the bytes that a
60/// corresponding `Serialize` would have produced for the returned value, no
61/// more and no fewer. On any malformed input it MUST return an error and
62/// MUST NOT panic, allocate unboundedly, or read past the decoder's
63/// underlying source.
64///
65/// Round-trip invariant:
66/// `decode::<T>(&encode(&v)?)? == v` for every `v: T`.
67///
68/// # Examples
69///
70/// ```
71/// use pack_io::{Decode, Decoder, Deserialize, Result, encode};
72///
73/// struct Point { x: i32, y: i32 }
74///
75/// impl Deserialize for Point {
76/// fn deserialize<D: Decode + ?Sized>(dec: &mut D) -> Result<Self> {
77/// Ok(Point {
78/// x: i32::deserialize(dec)?,
79/// y: i32::deserialize(dec)?,
80/// })
81/// }
82/// }
83///
84/// # impl pack_io::Serialize for Point {
85/// # fn serialize<E: pack_io::Encode + ?Sized>(&self, e: &mut E) -> Result<()> {
86/// # self.x.serialize(e)?;
87/// # self.y.serialize(e)
88/// # }
89/// # }
90/// let bytes = encode(&Point { x: 3, y: -7 }).unwrap();
91/// let mut dec = Decoder::new(&bytes);
92/// let back = Point::deserialize(&mut dec).unwrap();
93/// assert_eq!((back.x, back.y), (3, -7));
94/// ```
95pub trait Deserialize: Sized {
96 /// Read a value of `Self` from the decoder, advancing its cursor.
97 ///
98 /// # Errors
99 ///
100 /// Any [`crate::SerialError`] the underlying byte reads surface
101 /// (truncated input, invalid length prefix, hostile varint, …).
102 fn deserialize<D: Decode + ?Sized>(decoder: &mut D) -> Result<Self>;
103}