messagepack_core/decode/
map.rs

1use core::marker::PhantomData;
2
3use super::{Decode, Error, NbyteReader, Result};
4use crate::formats::Format;
5
6pub struct MapDecoder<Map, K, V>(PhantomData<(Map, K, V)>);
7
8fn decode_kv<'a, K, V>(buf: &'a [u8]) -> Result<(K::Value, V::Value, &'a [u8])>
9where
10    K: Decode<'a>,
11    V: Decode<'a>,
12{
13    let (k, buf) = K::decode(buf)?;
14    let (v, buf) = V::decode(buf)?;
15    Ok((k, v, buf))
16}
17
18impl<'a, Map, K, V> Decode<'a> for MapDecoder<Map, K, V>
19where
20    K: Decode<'a>,
21    V: Decode<'a>,
22    Map: FromIterator<(K::Value, V::Value)>,
23{
24    type Value = Map;
25
26    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
27        let (format, buf) = Format::decode(buf)?;
28        match format {
29            Format::FixMap(_) | Format::Map16 | Format::Map32 => {
30                Self::decode_with_format(format, buf)
31            }
32            _ => Err(Error::UnexpectedFormat),
33        }
34    }
35
36    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
37        let (len, buf) = match format {
38            Format::FixMap(len) => (len.into(), buf),
39            Format::Map16 => NbyteReader::<2>::read(buf)?,
40            Format::Map32 => NbyteReader::<4>::read(buf)?,
41            _ => return Err(Error::UnexpectedFormat),
42        };
43
44        let mut has_err = None;
45        let mut buf_ptr = buf;
46        let collector =
47            core::iter::repeat_n((), len).map_while(|_| match decode_kv::<K, V>(buf_ptr) {
48                Ok((k, v, b)) => {
49                    buf_ptr = b;
50                    Some((k, v))
51                }
52                Err(e) => {
53                    has_err = Some(e);
54                    None
55                }
56            });
57        let res = Map::from_iter(collector);
58
59        if let Some(e) = has_err {
60            Err(e)
61        } else {
62            Ok((res, buf_ptr))
63        }
64    }
65}