use crate::{
error::Result,
header::{CompactSeqHeader, ExtendedSeqHeader, SeqHeader},
io::Write,
num::WithPackedBeBytes as _,
value::{SeqValue, Value},
};
use super::Encoder;
impl<W> Encoder<W>
where
W: Write,
{
pub fn encode_seq(&mut self, value: &[Value]) -> Result<()> {
self.encode_seq_header(&self.header_for_seq_len(value.len()))?;
for value in value {
self.encode_value(value)?;
}
Ok(())
}
pub fn encode_seq_value(&mut self, value: &SeqValue) -> Result<()> {
self.encode_seq(&value.0)
}
pub fn encode_seq_header(&mut self, header: &SeqHeader) -> Result<()> {
let mut byte = SeqHeader::TYPE_BITS;
match *header {
SeqHeader::Compact(CompactSeqHeader { len }) => {
byte |= SeqHeader::COMPACT_VARIANT_BIT;
byte |= len & SeqHeader::COMPACT_LEN_BITS;
self.push_byte(byte)
}
SeqHeader::Extended(ExtendedSeqHeader { len }) => {
len.with_packed_be_bytes(self.config.lengths.packing, |bytes| {
let width = bytes.len() as u8;
byte |= (width - 1) & SeqHeader::EXTENDED_LEN_WIDTH_BITS;
#[cfg(feature = "tracing")]
tracing::debug!(
byte = crate::binary::fmt_byte(byte),
bytes = format!("{:b}", crate::binary::BytesSlice(bytes)),
len = len
);
self.push_byte(byte)?;
self.push_bytes(bytes)
})
}
}
}
pub fn header_for_seq_len(&self, len: usize) -> SeqHeader {
SeqHeader::for_len(len, self.config.lengths.packing)
}
}