use crate::{
de::CborDeserialize, error::SeaboredDeError, io::Read, mt::MajorType, types::CborIntegerValue,
};
pub mod consts {
pub const IB_SMALL_UINT: u8 = 0x00;
pub const IB_UINT_8: u8 = 0x18;
pub const IB_UINT_16: u8 = 0x19;
pub const IB_UINT_32: u8 = 0x1A;
pub const IB_UINT_64: u8 = 0x1B;
pub const IB_SMALL_NEGATIVE_UINT: u8 = 0x20;
pub const IB_NEGATIVE_UINT_8: u8 = 0x38;
pub const IB_NEGATIVE_UINT_16: u8 = 0x39;
pub const IB_NEGATIVE_UINT_32: u8 = 0x3A;
pub const IB_NEGATIVE_UINT_64: u8 = 0x3B;
pub const IB_SMALL_BYTE_STRING: u8 = 0x40;
pub const IB_BYTE_STRING_UINT_8_LEN: u8 = 0x58;
pub const IB_BYTE_STRING_UINT_16_LEN: u8 = 0x59;
pub const IB_BYTE_STRING_UINT_32_LEN: u8 = 0x5A;
pub const IB_BYTE_STRING_UINT_64_LEN: u8 = 0x5B;
pub const IB_BYTE_STRING_SEQUENCE_START: u8 = 0x5F;
pub const IB_SMALL_UTF_8_STRING: u8 = 0x60;
pub const IB_UTF_8_STRING_UINT_8_LEN: u8 = 0x78;
pub const IB_UTF_8_STRING_UINT_16_LEN: u8 = 0x79;
pub const IB_UTF_8_STRING_UINT_32_LEN: u8 = 0x7A;
pub const IB_UTF_8_STRING_UINT_64_LEN: u8 = 0x7B;
pub const IB_UTF_8_STRING_SEQUENCE_START: u8 = 0x7F;
pub const IB_SMALL_ARRAY: u8 = 0x80;
pub const IB_ARRAY_UINT_8_LEN: u8 = 0x98;
pub const IB_ARRAY_UINT_16_LEN: u8 = 0x99;
pub const IB_ARRAY_UINT_32_LEN: u8 = 0x9A;
pub const IB_ARRAY_UINT_64_LEN: u8 = 0x9B;
pub const IB_ARRAY_SEQUENCE_START: u8 = 0x9F;
pub const IB_SMALL_MAP: u8 = 0xA0;
pub const IB_MAP_UINT_8_LEN: u8 = 0xB8;
pub const IB_MAP_UINT_16_LEN: u8 = 0xB9;
pub const IB_MAP_UINT_32_LEN: u8 = 0xBA;
pub const IB_MAP_UINT_64_LEN: u8 = 0xBB;
pub const IB_MAP_SEQUENCE_START: u8 = 0xBF;
pub const IB_TAG_START_OR_DATE_TIME_TEXT: u8 = 0xC0;
pub const IB_DATE_TIME_EPOCH: u8 = 0xC1;
pub const IB_UNSIGNED_BIG_NUM: u8 = 0xC2;
pub const IB_NEGATIVE_BIG_NUM: u8 = 0xC3;
pub const IB_DECIMAL_FRACTION: u8 = 0xC4;
pub const IB_BIG_FLOAT: u8 = 0xC5;
pub const IB_EXPECTED_CONVERSION_BASE_64_NO_PAD: u8 = 0xD5;
pub const IB_EXPECTED_CONVERSION_BASE_64_PAD: u8 = 0xD6;
pub const IB_EXPECTED_CONVERSION_HEX_UPPER: u8 = 0xD7;
pub const IB_TAG_NEXT_UINT_8: u8 = 0xD8;
pub const IB_TAG_NEXT_UINT_16: u8 = 0xD9;
pub const IB_TAG_NEXT_UINT_32: u8 = 0xDA;
pub const IB_TAG_NEXT_UINT_64: u8 = 0xDB;
pub const IB_SIMPLE_VALUE: u8 = 0xE0;
pub const IB_FALSE: u8 = 0xF4;
pub const IB_TRUE: u8 = 0xF5;
pub const IB_NULL: u8 = 0xF6;
pub const IB_UNDEFINED: u8 = 0xF7;
pub const IB_SIMPLE_VALUE_NEXT_BYTE: u8 = 0xF8;
pub const IB_FLOAT_16: u8 = 0xF9;
pub const IB_FLOAT_32: u8 = 0xFA;
pub const IB_FLOAT_64: u8 = 0xFB;
pub const IB_BREAK: u8 = 0xFF;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct InitialByte(pub(crate) u8);
impl From<MajorType> for InitialByte {
#[inline(always)]
fn from(value: MajorType) -> Self {
unsafe { std::mem::transmute((value as u8) << 5) }
}
}
impl<'a> CborDeserialize<'a> for InitialByte {
#[inline(always)]
fn cbor_deserialize_from<R: Read<'a>>(reader: &mut R) -> Result<Self, SeaboredDeError<'a>> {
reader.read_byte().map(InitialByte)
}
}
impl std::ops::Deref for InitialByte {
type Target = u8;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl InitialByte {
#[inline(always)]
pub fn mt(&self) -> MajorType {
MajorType::from(*self)
}
#[inline(always)]
pub fn ai(&self) -> AdditionalInfo {
AdditionalInfo::from(*self)
}
#[inline(always)]
pub fn mt_ai(&self) -> (MajorType, AdditionalInfo) {
(self.mt(), self.ai())
}
#[inline(always)]
pub fn peek<'a, R: Read<'a>>(reader: &mut R) -> Result<Self, SeaboredDeError<'a>> {
reader.peek_byte().map(Self)
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct AdditionalInfo(pub(crate) u8);
impl AdditionalInfo {
#[inline(always)]
pub(crate) fn action<'a>(&self) -> Result<AdditionalInfoAction, SeaboredDeError<'a>> {
Ok(match self.0 {
24 => AdditionalInfoAction::Uint8,
25 => AdditionalInfoAction::Uint16,
26 => AdditionalInfoAction::Uint32,
27 => AdditionalInfoAction::Uint64,
28..31 => return Err(SeaboredDeError::IllegalAdditionalInfo(self.0)),
31 => AdditionalInfoAction::IndefiniteLenSeq,
_ => AdditionalInfoAction::DoNothing,
})
}
#[cfg_attr(feature = "inline-nontrivial", inline)]
pub(crate) fn find_subsequent_len<'data, R: Read<'data>>(
&self,
reader: &mut R,
) -> Result<CborIntegerValue, SeaboredDeError<'data>> {
Ok(match self.action()? {
crate::ib::AdditionalInfoAction::DoNothing => CborIntegerValue::from(self.0),
crate::ib::AdditionalInfoAction::Uint8 => CborIntegerValue::from(reader.read_byte()?),
crate::ib::AdditionalInfoAction::Uint16 => {
CborIntegerValue::from(reader.read_be_u16()?)
}
crate::ib::AdditionalInfoAction::Uint32 => {
CborIntegerValue::from(reader.read_be_u32()?)
}
crate::ib::AdditionalInfoAction::Uint64 => {
CborIntegerValue::from(reader.read_be_u64()?)
}
crate::ib::AdditionalInfoAction::IndefiniteLenSeq => {
return Err(SeaboredDeError::IndefiniteLen);
}
})
}
}
impl From<InitialByte> for AdditionalInfo {
#[inline(always)]
fn from(value: InitialByte) -> Self {
Self(value.0 & 0x1f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(u8)]
pub(crate) enum AdditionalInfoAction {
#[default]
DoNothing = 0,
Uint8 = 1 << 0,
Uint16 = 1 << 1,
Uint32 = 1 << 2,
Uint64 = 1 << 3,
IndefiniteLenSeq = consts::IB_BREAK, }