lilliput_core/encoder/
map.rs1use crate::{
2 error::Result,
3 header::{CompactMapHeader, ExtendedMapHeader, MapHeader},
4 io::Write,
5 num::WithPackedBeBytes as _,
6 value::{Map, MapValue},
7};
8
9use super::Encoder;
10
11impl<W> Encoder<W>
12where
13 W: Write,
14{
15 pub fn encode_map(&mut self, value: &Map) -> Result<()> {
19 self.encode_map_header(&self.header_for_map_len(value.len()))?;
20
21 for (key, value) in value {
22 self.encode_value(key)?;
23 self.encode_value(value)?;
24 }
25
26 Ok(())
27 }
28
29 pub fn encode_map_value(&mut self, value: &MapValue) -> Result<()> {
31 self.encode_map(&value.0)
32 }
33
34 pub fn encode_map_header(&mut self, header: &MapHeader) -> Result<()> {
38 let mut byte = MapHeader::TYPE_BITS;
39
40 match *header {
41 MapHeader::Compact(CompactMapHeader { len }) => {
42 byte |= MapHeader::COMPACT_VARIANT_BIT;
43 byte |= len & MapHeader::COMPACT_LEN_BITS;
44
45 self.push_byte(byte)
47 }
48 MapHeader::Extended(ExtendedMapHeader { len }) => {
49 len.with_packed_be_bytes(self.config.lengths.packing, |bytes| {
50 let width = bytes.len() as u8;
51
52 byte |= (width - 1) & MapHeader::EXTENDED_LEN_WIDTH_BITS;
53
54 #[cfg(feature = "tracing")]
55 tracing::debug!(
56 byte = crate::binary::fmt_byte(byte),
57 bytes = format!("{:b}", crate::binary::BytesSlice(bytes)),
58 len = len
59 );
60
61 self.push_byte(byte)?;
63
64 self.push_bytes(bytes)
66 })
67 }
68 }
69 }
70
71 pub fn header_for_map_len(&self, len: usize) -> MapHeader {
73 MapHeader::for_len(len, self.config.lengths.packing)
74 }
75}