Skip to main content

wire_repr/codec/
plan.rs

1/// A completed, infallible encoding operation.
2///
3/// Implementations perform all fallible work while they are created. `write_into`
4/// therefore only copies already-prepared bytes into an exactly-sized output slice.
5pub trait EncodePlan {
6    /// Returns the exact number of bytes written by [`Self::write_into`].
7    #[must_use]
8    fn encoded_len(&self) -> usize;
9
10    /// Writes this plan into `output`.
11    ///
12    /// `output` must have length [`Self::encoded_len`]. Passing another length is a
13    /// contract violation and may panic; implementations must not silently succeed
14    /// without writing the complete encoding.
15    fn write_into(&self, output: &mut [u8]);
16}
17
18/// A prepared layout encoding that can be committed into an output buffer.
19///
20/// Preparation performs every fallible codec operation. Implementations only check
21/// output capacity and copy already-prepared encodings when committed.
22pub trait PreparedLayout {
23    /// The mutable view returned over the committed layout bytes.
24    type ViewMut<'output>;
25
26    /// Returns the exact number of output bytes required for this layout.
27    #[must_use]
28    fn encoded_len(&self) -> usize;
29
30    /// Commits this prepared layout into the leading output bytes.
31    ///
32    /// Extra output bytes are returned as a disjoint suffix. A short output is left
33    /// unchanged.
34    fn commit_into<'output>(
35        self,
36        output: &'output mut [u8],
37    ) -> Result<(Self::ViewMut<'output>, &'output mut [u8]), OutputTooShortError>;
38}
39
40/// Reports that an output buffer cannot contain a prepared layout.
41#[derive(Clone, Copy, Debug, Eq, PartialEq)]
42pub struct OutputTooShortError {
43    /// The exact number of bytes required by the prepared layout.
44    pub required: usize,
45    /// The number of bytes available in the supplied output buffer.
46    pub available: usize,
47}
48
49impl core::fmt::Display for OutputTooShortError {
50    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51        write!(
52            formatter,
53            "output too short: need {} bytes, got {}",
54            self.required, self.available
55        )
56    }
57}
58
59impl core::error::Error for OutputTooShortError {}
60
61impl<const N: usize> EncodePlan for [u8; N] {
62    #[inline]
63    fn encoded_len(&self) -> usize {
64        N
65    }
66
67    #[inline]
68    fn write_into(&self, output: &mut [u8]) {
69        output.copy_from_slice(self);
70    }
71}
72
73impl EncodePlan for &[u8] {
74    #[inline]
75    fn encoded_len(&self) -> usize {
76        self.len()
77    }
78
79    #[inline]
80    fn write_into(&self, output: &mut [u8]) {
81        output.copy_from_slice(self);
82    }
83}