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}