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> {}