1use core::marker::PhantomData;
4
5use super::{DecodeBorrowed, Error, NbyteReader};
6use crate::{formats::Format, io::IoRead};
7
8pub struct MapDecoder<Map, K, V>(PhantomData<(Map, K, V)>);
10
11#[allow(clippy::type_complexity)]
12fn decode_kv<'de, R, K, V>(reader: &mut R) -> Result<(K::Value, V::Value), Error<R::Error>>
13where
14 R: IoRead<'de>,
15 K: DecodeBorrowed<'de>,
16 V: DecodeBorrowed<'de>,
17{
18 let k = K::decode_borrowed(reader)?;
19 let v = V::decode_borrowed(reader)?;
20 Ok((k, v))
21}
22
23impl<'de, Map, K, V> DecodeBorrowed<'de> for MapDecoder<Map, K, V>
24where
25 K: DecodeBorrowed<'de>,
26 V: DecodeBorrowed<'de>,
27 Map: FromIterator<(K::Value, V::Value)>,
28{
29 type Value = Map;
30
31 fn decode_borrowed_with_format<R>(
32 format: Format,
33 reader: &mut R,
34 ) -> Result<Self::Value, Error<R::Error>>
35 where
36 R: IoRead<'de>,
37 {
38 let len = match format {
39 Format::FixMap(len) => len.into(),
40 Format::Map16 => NbyteReader::<2>::read(reader)?,
41 Format::Map32 => NbyteReader::<4>::read(reader)?,
42 _ => return Err(Error::UnexpectedFormat),
43 };
44
45 let mut err: Option<Error<R::Error>> = None;
46 let iter = (0..len).map_while(|_| match decode_kv::<R, K, V>(reader) {
47 Ok((k, v)) => Some((k, v)),
48 Err(e) => {
49 err = Some(e);
50 None
51 }
52 });
53 let res = Map::from_iter(iter);
54 match err {
55 Some(e) => Err(e),
56 None => Ok(res),
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use crate::decode::Decode;
65 use rstest::rstest;
66
67 #[rstest]
68 #[case(&[0x82, 0x01, 0x0a, 0x02, 0x14], vec![(1u8, 10u8), (2, 20)], &[])]
69 #[case(&[0xde, 0x00, 0x02, 0x01, 0x0a, 0x02, 0x14], vec![(1u8, 10u8), (2, 20)], &[])]
70 fn map_decode_success(
71 #[case] buf: &[u8],
72 #[case] expect: Vec<(u8, u8)>,
73 #[case] rest_expect: &[u8],
74 ) {
75 let mut r = crate::io::SliceReader::new(buf);
76 let decoded = MapDecoder::<Vec<(u8, u8)>, u8, u8>::decode(&mut r).unwrap();
77 assert_eq!(decoded, expect);
78 assert_eq!(r.rest(), rest_expect);
79 }
80
81 #[test]
82 fn map_decoder_unexpected_format() {
83 let buf = &[0x91, 0x00];
85 let mut r = crate::io::SliceReader::new(buf);
86 let err = MapDecoder::<Vec<(u8, u8)>, u8, u8>::decode(&mut r).unwrap_err();
87 assert!(matches!(err, Error::UnexpectedFormat));
88 }
89
90 #[test]
91 fn map_decode_eof_on_key() {
92 let buf = &[0x81];
94 let mut r = crate::io::SliceReader::new(buf);
95 let err = MapDecoder::<Vec<(u8, u8)>, u8, u8>::decode(&mut r).unwrap_err();
96 assert!(matches!(err, Error::Io(_)));
97 }
98
99 #[test]
100 fn map_decode_key_unexpected_format() {
101 let buf = &[0x81, 0xa1, b'a', 0x02];
103 let mut r = crate::io::SliceReader::new(buf);
104 let err = MapDecoder::<Vec<(u8, u8)>, u8, u8>::decode(&mut r).unwrap_err();
105 assert!(matches!(err, Error::UnexpectedFormat));
106 }
107
108 #[test]
109 fn map_decode_value_error_after_first_pair() {
110 let buf = &[0x82, 0x01, 0x01, 0x02];
112 let mut r = crate::io::SliceReader::new(buf);
113 let err = MapDecoder::<Vec<(u8, u8)>, u8, u8>::decode(&mut r).unwrap_err();
114 assert!(matches!(err, Error::Io(_)));
116 }
117}