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}