use crate::{ib, io::Write, mt::MajorType, ser::CborSerialize, types::CborIntegerValue};
const MAX_PREALLOC_CAPACITY: usize = 256;
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct CborSequence<T: CborSerialize> {
inner: Vec<T>,
pub mt: MajorType,
pub is_indefinite: bool,
}
impl<T: CborSerialize> Default for CborSequence<T> {
#[inline(always)]
fn default() -> Self {
Self {
inner: Default::default(),
mt: MajorType::Array,
is_indefinite: Default::default(),
}
}
}
impl<T: CborSerialize> CborSequence<T> {
#[inline(always)]
pub fn new_finite(mt: MajorType, len: usize) -> Self {
Self {
inner: Vec::with_capacity(len.min(MAX_PREALLOC_CAPACITY)),
mt,
is_indefinite: false,
}
}
#[inline(always)]
pub fn new_indefinite(mt: MajorType) -> Self {
Self {
inner: Vec::with_capacity(MAX_PREALLOC_CAPACITY),
mt,
is_indefinite: true,
}
}
#[inline(always)]
pub fn with_mt(mut self, mt: MajorType) -> Self {
self.mt = mt;
self
}
}
impl<T: CborSerialize> std::ops::Deref for CborSequence<T> {
type Target = Vec<T>;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T: CborSerialize> std::ops::DerefMut for CborSequence<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<T: CborSerialize> From<Vec<T>> for CborSequence<T> {
#[inline(always)]
fn from(inner: Vec<T>) -> Self {
Self {
inner,
mt: MajorType::Array,
is_indefinite: false,
}
}
}
impl<T: CborSerialize> CborSerialize for CborSequence<T> {
#[cfg_attr(feature = "inline-nontrivial", inline)]
fn cbor_serialize_to<W: Write>(
&self,
writer: &mut W,
) -> Result<usize, crate::error::SeaboredSerError> {
let mut written = if self.is_indefinite {
writer.write(&[((self.mt as u8) << 5u8) | 0x1F])?
} else {
CborIntegerValue::from(self.inner.len())
.serialize_complex_mt_preamble(self.mt, writer)?
};
for value in &self.inner {
written += value.cbor_serialize_to(writer)?;
}
if self.is_indefinite {
written += writer.write(&[ib::consts::IB_BREAK])?;
}
Ok(written)
}
}