tokio_util_codec_compose/decode/adaptors/
map.rs1use bytes::BytesMut;
4use std::io;
5use tokio_util::codec::Decoder;
6
7#[must_use = "decoders do nothing unless used"]
11#[derive(Debug)]
12pub struct DecoderMap<D, F> {
13 inner: D,
14 f: F,
15}
16
17impl<D, F> DecoderMap<D, F> {
18 pub(in crate::decode) fn new(inner: D, f: F) -> Self {
19 Self { inner, f }
20 }
21}
22
23impl<D, F, A, B, E> Decoder for DecoderMap<D, F>
24where
25 D: Decoder<Item = A, Error = E>,
26 F: Fn(A) -> B,
27 E: From<io::Error>,
28{
29 type Item = B;
30
31 type Error = E;
32
33 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
34 Ok(self.inner.decode(src)?.map(&self.f))
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 use crate::{decode::DecoderExt, primitives::uint8};
43
44 use proptest::prelude::*;
45 use std::{convert::identity as id, fmt::Debug};
46 use tokio_util::codec::BytesCodec;
47
48 proptest! {
51 #[test]
52 fn decode_map_check_law_map_id(src in bytes()) {
53 let src = BytesMut::from(src.as_slice());
55 let decoder = BytesCodec::default();
56 decode_map_law_map_id_succeed(decoder, src);
57 }
58 }
59
60 #[track_caller]
61 fn decode_map_law_map_id_succeed<D, A, E>(mut decoder: D, mut src: BytesMut)
62 where
63 D: Decoder<Item = A, Error = E> + Clone,
64 A: PartialEq + Debug,
65 E: Debug + From<io::Error>,
66 {
67 let mut src_mapped = src.clone();
68 let mut decoder_mapped = decoder.clone().map(id);
69
70 let res = decoder.decode(&mut src).unwrap();
71 let res_mapped = decoder_mapped.decode(&mut src_mapped).unwrap();
72
73 assert_eq!(res, res_mapped);
74 assert_eq!(src, src_mapped);
75 }
76
77 fn bytes() -> impl Strategy<Value = Vec<u8>> {
78 proptest::collection::vec(any::<u8>(), 0..255)
79 }
80
81 #[test]
82 fn decode_map() -> anyhow::Result<()> {
83 let mut decoder = uint8().map(Device);
84
85 let mut src = BytesMut::from("\x01");
86 let value = decoder.decode(&mut src)?;
87
88 assert!(matches!(value, Some(Device(0x01))));
89 assert_eq!(src, BytesMut::default());
90
91 Ok(())
92 }
93
94 #[derive(Debug, PartialEq, Eq)]
95 struct Device(u8);
96}