Skip to main content

wire_codec/
traits.rs

1//! Core traits implemented by every encodable value.
2//!
3//! [`Encode`] writes a value into a [`WriteBuf`]; [`Decode`] reads one out of a
4//! [`ReadBuf`]. The traits are deliberately minimal so callers can compose them
5//! with any framing strategy in the [`framing`][`crate::framing`] module.
6
7use crate::buf::{ReadBuf, WriteBuf};
8use crate::error::Result;
9
10/// A value that can be written to a [`WriteBuf`].
11///
12/// Implementors must guarantee that [`Encode::encoded_size`] returns the exact
13/// number of bytes [`Encode::encode`] writes on success.
14///
15/// # Example
16///
17/// ```
18/// use wire_codec::{Encode, Result, WriteBuf};
19///
20/// struct Tagged {
21///     tag: u8,
22///     value: u32,
23/// }
24///
25/// impl Encode for Tagged {
26///     fn encoded_size(&self) -> usize { 5 }
27///     fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
28///         buf.write_u8(self.tag)?;
29///         buf.write_u32_be(self.value)
30///     }
31/// }
32///
33/// let mut out = [0u8; 5];
34/// let mut buf = WriteBuf::new(&mut out);
35/// Tagged { tag: 0x01, value: 0xCAFEBABE }.encode(&mut buf).unwrap();
36/// assert_eq!(&out, &[0x01, 0xCA, 0xFE, 0xBA, 0xBE]);
37/// ```
38pub trait Encode {
39    /// Number of bytes [`Encode::encode`] will write on success.
40    fn encoded_size(&self) -> usize;
41
42    /// Write `self` into `buf`, advancing its write position.
43    ///
44    /// # Errors
45    ///
46    /// Returns an error if `buf` lacks capacity for [`Encode::encoded_size`]
47    /// bytes or if a sub-encoder reports an invariant violation.
48    fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()>;
49}
50
51/// A value that can be read from a [`ReadBuf`].
52///
53/// The lifetime parameter `'de` ties the decoded value to the borrowed input,
54/// enabling zero-copy decoding of borrowed payloads (`&'de [u8]`, `&'de str`).
55///
56/// # Example
57///
58/// ```
59/// use wire_codec::{Decode, ReadBuf, Result};
60///
61/// struct Tagged {
62///     tag: u8,
63///     value: u32,
64/// }
65///
66/// impl<'de> Decode<'de> for Tagged {
67///     fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
68///         let tag = buf.read_u8()?;
69///         let value = buf.read_u32_be()?;
70///         Ok(Self { tag, value })
71///     }
72/// }
73///
74/// let mut buf = ReadBuf::new(&[0x01, 0xCA, 0xFE, 0xBA, 0xBE]);
75/// let tagged = Tagged::decode(&mut buf).unwrap();
76/// assert_eq!(tagged.tag, 0x01);
77/// assert_eq!(tagged.value, 0xCAFEBABE);
78/// ```
79pub trait Decode<'de>: Sized {
80    /// Read a value of `Self` from `buf`, advancing its read position.
81    ///
82    /// # Errors
83    ///
84    /// Returns an error if `buf` is exhausted before the value finishes, or if
85    /// the encoded bytes violate the codec's structural rules.
86    fn decode(buf: &mut ReadBuf<'de>) -> Result<Self>;
87}
88
89impl Encode for u8 {
90    #[inline]
91    fn encoded_size(&self) -> usize {
92        1
93    }
94    #[inline]
95    fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
96        buf.write_u8(*self)
97    }
98}
99
100impl<'de> Decode<'de> for u8 {
101    #[inline]
102    fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
103        buf.read_u8()
104    }
105}