lilliput_core/decoder/
map.rs1use crate::{
2 error::Result,
3 header::MapHeader,
4 marker::Marker,
5 value::{Map, MapValue},
6};
7
8use super::{Decoder, Read};
9
10impl<'de, R> Decoder<R>
11where
12 R: Read<'de>,
13{
14 #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
18 pub fn decode_map(&mut self) -> Result<Map> {
19 let header = self.decode_map_header()?;
20 self.decode_map_of(header)
21 }
22
23 #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
25 pub fn decode_map_value(&mut self) -> Result<MapValue> {
26 self.decode_map().map(From::from)
27 }
28
29 #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
33 pub fn decode_map_header(&mut self) -> Result<MapHeader> {
34 let byte = self.pull_byte_expecting(Marker::Map)?;
35
36 let is_compact = (byte & MapHeader::COMPACT_VARIANT_BIT) != 0b0;
37
38 if is_compact {
39 let len = byte & MapHeader::COMPACT_LEN_BITS;
40
41 #[cfg(feature = "tracing")]
42 tracing::debug!(
43 byte = crate::binary::fmt_byte(byte),
44 is_compact = true,
45 len = len
46 );
47
48 Ok(MapHeader::compact(len))
49 } else {
50 let len_width = 1 + (byte & MapHeader::EXTENDED_LEN_WIDTH_BITS);
51 let len = self.pull_len_bytes(len_width)?;
52
53 #[cfg(feature = "tracing")]
54 tracing::debug!(
55 byte = crate::binary::fmt_byte(byte),
56 is_compact = false,
57 len = len
58 );
59
60 Ok(MapHeader::extended(len))
61 }
62 }
63
64 #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
68 pub fn skip_map_value_of(&mut self, header: MapHeader) -> Result<()> {
69 let len: usize = match header {
70 MapHeader::Compact(header) => header.len().into(),
71 MapHeader::Extended(header) => header.len(),
72 };
73
74 for _ in 0..len {
75 self.skip_value()?; self.skip_value()?; }
78
79 Ok(())
80 }
81
82 #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
86 pub fn decode_map_value_of(&mut self, header: MapHeader) -> Result<MapValue> {
87 self.decode_map_of(header).map(From::from)
88 }
89
90 #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
94 fn decode_map_of(&mut self, header: MapHeader) -> Result<Map> {
95 let mut map = Map::default();
96
97 for _ in 0..header.len() {
98 let key = self.decode_value()?;
99 let value = self.decode_value()?;
100 map.insert(key, value);
101 }
102
103 Ok(map)
104 }
105}