encode/encoders/size.rs
1use crate::Encoder;
2
3/// An encoder that counts the size of the encoded data.
4///
5/// This encoder is useful for calculating the size of the encoded data without
6/// actually encoding it, allowing you to pre-allocate a buffer of the correct
7/// size before encoding the data.
8///
9/// Note that this encoder runs all the same encoding logic as any other encoder,
10/// so it will trigger the same side effects that other encoders would trigger
11/// (e.g Allocations). See the [`Encodable`] trait for more information on
12/// idempotent encodes.
13///
14/// # Example
15///
16/// ```
17/// use encode::Encoder;
18/// use encode::Encodable;
19/// use encode::encoders::SizeEncoder;
20///
21/// let encodable = c"hello, world!";
22/// let mut encoder = SizeEncoder::new();
23/// encodable.encode(&mut encoder).unwrap();
24/// assert_eq!(encoder.size(), 14, "13 bytes from the ASCII string and 1 byte for the null terminator");
25/// ```
26///
27/// [`Encodable`]: crate::Encodable
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
29pub struct SizeEncoder {
30 size: usize,
31}
32
33impl SizeEncoder {
34 /// Creates a new [`SizeEncoder`].
35 #[inline]
36 #[must_use]
37 pub fn new() -> Self {
38 Self::default()
39 }
40
41 /// Returns the size of the encoded data.
42 #[inline]
43 #[must_use]
44 pub fn size(&self) -> usize {
45 (*self).into()
46 }
47}
48
49impl From<SizeEncoder> for usize {
50 fn from(encoder: SizeEncoder) -> usize {
51 encoder.size
52 }
53}
54
55impl core::fmt::Write for SizeEncoder {
56 fn write_str(&mut self, s: &str) -> core::fmt::Result {
57 self.size += s.len();
58 Ok(())
59 }
60}
61
62impl Encoder for SizeEncoder {
63 type Error = core::convert::Infallible;
64
65 #[inline]
66 fn put_slice(&mut self, slice: &[u8]) -> Result<(), Self::Error> {
67 self.size += slice.len();
68 Ok(())
69 }
70
71 #[inline]
72 fn put_byte(&mut self, _byte: u8) -> Result<(), Self::Error> {
73 self.size += 1;
74 Ok(())
75 }
76}