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}