tokio_util_codec_compose/encode/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//! A set compositional operations on [`Encoder`].
//!
//! The operations take simpler encoders as inputs with customization functions and produce more powerful ones as output.

pub mod adaptors;

use self::adaptors::EncoderContraMap;

use tokio_util::codec::Encoder;

/// Extension of [`Encoder`] with compositional operations.
pub trait EncoderExt<A, E>: Encoder<A, Error = E> {
    /// Applies a function `f` of type `B -> A` over the input before encoding.
    ///
    /// So, if you have a value of type `A` for which there's an `Encoder<A>`, and you have a function `B -> A`,
    /// then you can obtain an `Encoder<B>`. Notice that the arrows are "reversed" if compared
    /// against a typical `map` operation.
    ///
    /// The function `f` cannot fail.
    ///
    /// # Examples
    ///
    /// ```
    /// # use tokio_util::codec::Encoder;
    /// # use bytes::BytesMut;
    /// use tokio_util_codec_compose::{encode::EncoderExt, primitives::uint8};
    ///
    /// # #[derive(Debug, PartialEq, Eq)]
    /// struct Device(u8);
    ///
    /// let mut dst = BytesMut::default();
    /// let device = uint8().contra_map(|d: Device| d.0).encode(Device(0x01), &mut dst).unwrap();
    /// assert_eq!(dst, BytesMut::from("\x01"));
    /// ```
    fn contra_map<F, B>(self, f: F) -> EncoderContraMap<Self, F>
    where
        F: Fn(B) -> A,
        Self: Sized,
    {
        EncoderContraMap::new(self, f)
    }
}

impl<C, A, E> EncoderExt<A, E> for C where C: Encoder<A, Error = E> {}