tokio_util_codec_compose/encode/
mod.rs

1//! A set compositional operations on [`Encoder`].
2//!
3//! The operations take simpler encoders as inputs with customization functions and produce more powerful ones as output.
4
5pub mod adaptors;
6
7use self::adaptors::EncoderContraMap;
8
9use tokio_util::codec::Encoder;
10
11/// Extension of [`Encoder`] with compositional operations.
12pub trait EncoderExt<A, E>: Encoder<A, Error = E> {
13    /// Applies a function `f` of type `B -> A` over the input before encoding.
14    ///
15    /// So, if you have a value of type `A` for which there's an `Encoder<A>`, and you have a function `B -> A`,
16    /// then you can obtain an `Encoder<B>`. Notice that the arrows are "reversed" if compared
17    /// against a typical `map` operation.
18    ///
19    /// The function `f` cannot fail.
20    ///
21    /// # Examples
22    ///
23    /// ```
24    /// # use tokio_util::codec::Encoder;
25    /// # use bytes::BytesMut;
26    /// use tokio_util_codec_compose::{encode::EncoderExt, primitives::uint8};
27    ///
28    /// # #[derive(Debug, PartialEq, Eq)]
29    /// struct Device(u8);
30    ///
31    /// let mut dst = BytesMut::default();
32    /// let device = uint8().contra_map(|d: Device| d.0).encode(Device(0x01), &mut dst).unwrap();
33    /// assert_eq!(dst, BytesMut::from("\x01"));
34    /// ```
35    fn contra_map<F, B>(self, f: F) -> EncoderContraMap<Self, F>
36    where
37        F: Fn(B) -> A,
38        Self: Sized,
39    {
40        EncoderContraMap::new(self, f)
41    }
42}
43
44impl<C, A, E> EncoderExt<A, E> for C where C: Encoder<A, Error = E> {}