encode/
lib.rs

1#![doc = include_str!("../README.md")]
2#![forbid(
3    missing_docs,
4    missing_debug_implementations,
5    unsafe_code,
6    clippy::std_instead_of_core,
7    clippy::std_instead_of_alloc,
8    clippy::dbg_macro,
9    clippy::exit,
10    clippy::infinite_loop,
11    clippy::mem_forget,
12    clippy::panic,
13    clippy::cargo,
14    clippy::missing_const_for_fn,
15    clippy::tabs_in_doc_comments,
16    clippy::perf
17)]
18#![warn(clippy::pedantic)]
19#![cfg_attr(not(feature = "std"), no_std)]
20
21#[cfg(feature = "alloc")]
22extern crate alloc;
23
24pub mod combinators;
25pub mod encoders;
26mod impls;
27
28/// A type that can be encoded into an encoder.
29///
30/// An encoder must be pure, meaning that it has to uphold the following properties:
31///
32/// - It must have no side effects
33/// - It must produce the same outputs for the same inputs
34///
35/// Some examples of non-indepotent encodes are:
36///
37/// - Writing to a file or other I/O device
38/// - Using random number generators
39/// - Panics
40/// - Using global state
41pub trait Encodable<E>
42where
43    E: Encoder,
44{
45    /// The error type that can be returned when encoding `self`.
46    ///
47    /// For example, some encodables may abort encoding if encoding would produce
48    /// an invalid byte stream as dictated by the encoding format.
49    type Error: From<E::Error>;
50
51    /// Encodes `self` into the given `encoder`.
52    ///
53    /// # Errors
54    ///
55    /// Implementations of this method should return an error if encoding fails
56    /// due to an encoder error or if the encoding would produce an invalid byte
57    /// stream as dictated by the encoding format.
58    fn encode(&self, encoder: &mut E) -> Result<(), Self::Error>;
59}
60
61/// A type that can handle an [`Encodable`] type
62///
63/// An encoder is responsible for writing bytes into a buffer or other
64/// destination. Encoders are used by encodables to write their data. Thus,
65/// encoders must uphold the same properties as encodables.
66pub trait Encoder {
67    /// The error type that can be returned when encoding a value.
68    ///
69    /// For example, some encoders may return an error if the underlying buffer
70    /// is full
71    type Error;
72
73    /// Copies a slice of bytes into the encoder
74    ///
75    /// # Errors
76    ///
77    /// Implementations of this method should return an error if the underlying
78    /// encoder fails to write the slice of bytes.
79    fn put_slice(&mut self, slice: &[u8]) -> Result<(), Self::Error>;
80    /// Appends a single byte into the encoder, if possible.
81    ///
82    /// # Errors
83    ///
84    /// Implementations of this method should return an error if the underlying
85    /// encoder fails to write the byte.
86    fn put_byte(&mut self, byte: u8) -> Result<(), Self::Error>;
87}
88
89/// An extension trait for types that can calculate the size of their encoded form.
90///
91/// This trait is implemented for all types that implement the [`Encodable`] trait for [`SizeEncoder`].
92///
93/// See the [`SizeEncoder`] encoder for more information.
94///
95/// [`SizeEncoder`]: encoders::SizeEncoder
96pub trait EncodableSize: Encodable<encoders::SizeEncoder> {
97    /// Returns the size of the encoded form of `self`.
98    ///
99    /// # Errors
100    ///
101    /// If encoding fails, this method will return an error.
102    fn encoded_size(&self) -> Result<usize, Self::Error>;
103}
104
105impl<T> EncodableSize for T
106where
107    T: Encodable<encoders::SizeEncoder>,
108{
109    #[inline]
110    fn encoded_size(&self) -> Result<usize, Self::Error> {
111        let mut encoder = encoders::SizeEncoder::new();
112        self.encode(&mut encoder)?;
113        Ok(encoder.size())
114    }
115}