#![cfg_attr(not(feature = "python-bindings"), no_std)]
pub use cbor_decoder::*;
pub use edhoc_parser::*;
pub use helpers::*;
mod crypto;
pub use crypto::Crypto;
mod cred;
pub use cred::*;
#[cfg(feature = "python-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "python-bindings")]
mod python_bindings;
pub const MAX_MESSAGE_SIZE_LEN: usize = 128 + 64;
pub const ID_CRED_LEN: usize = 4;
pub const SUITES_LEN: usize = 9;
pub const SUPPORTED_SUITES_LEN: usize = 1;
pub const EDHOC_METHOD: u8 = 3u8; pub const P256_ELEM_LEN: usize = 32;
pub const SHA256_DIGEST_LEN: usize = 32;
pub const AES_CCM_KEY_LEN: usize = 16;
pub const AES_CCM_IV_LEN: usize = 13;
pub const AES_CCM_TAG_LEN: usize = 8;
pub const MAC_LENGTH: usize = 8; pub const MAC_LENGTH_2: usize = MAC_LENGTH;
pub const MAC_LENGTH_3: usize = MAC_LENGTH_2;
pub const ENCODED_VOUCHER_LEN: usize = 1 + MAC_LENGTH; pub const MAX_KDF_CONTEXT_LEN: usize = 150;
pub const MAX_KDF_LABEL_LEN: usize = 15; pub const MAX_BUFFER_LEN: usize = 256;
pub const CBOR_BYTE_STRING: u8 = 0x58u8;
pub const CBOR_TEXT_STRING: u8 = 0x78u8;
pub const CBOR_UINT_1BYTE: u8 = 0x18u8;
pub const CBOR_NEG_INT_1BYTE_START: u8 = 0x20u8;
pub const CBOR_NEG_INT_1BYTE_END: u8 = 0x37u8;
pub const CBOR_UINT_1BYTE_START: u8 = 0x0u8;
pub const CBOR_UINT_1BYTE_END: u8 = 0x17u8;
pub const CBOR_MAJOR_TEXT_STRING: u8 = 0x60u8;
pub const CBOR_MAJOR_BYTE_STRING: u8 = 0x40u8;
pub const CBOR_MAJOR_BYTE_STRING_MAX: u8 = 0x57u8;
pub const CBOR_MAJOR_ARRAY: u8 = 0x80u8;
pub const CBOR_MAJOR_ARRAY_MAX: u8 = 0x97u8;
pub const MAX_INFO_LEN: usize = 2 + SHA256_DIGEST_LEN + 1 + MAX_KDF_LABEL_LEN +     1 + MAX_KDF_CONTEXT_LEN +   1; pub const ENC_STRUCTURE_LEN: usize = 8 + 5 + SHA256_DIGEST_LEN; pub const MAX_EAD_SIZE_LEN: usize = 64;
pub const EAD_ZEROCONF_LABEL: u8 = 0x1; pub const EAD_ZEROCONF_INFO_K_1_LABEL: u8 = 0x0;
pub const EAD_ZEROCONF_INFO_IV_1_LABEL: u8 = 0x1;
pub const EAD_ZEROCONF_ENC_STRUCTURE_LEN: usize = 2 + 8 + 3;
pub type BytesSuites = [u8; SUITES_LEN];
pub type BytesSupportedSuites = [u8; SUPPORTED_SUITES_LEN];
pub const EDHOC_SUITES: BytesSuites = [0, 1, 2, 3, 4, 5, 6, 24, 25]; pub const EDHOC_SUPPORTED_SUITES: BytesSupportedSuites = [0x2u8];
pub type BytesEad2 = [u8; 0];
pub type BytesIdCred = [u8; ID_CRED_LEN];
pub type Bytes8 = [u8; 8];
pub type BytesCcmKeyLen = [u8; AES_CCM_KEY_LEN];
pub type BytesCcmIvLen = [u8; AES_CCM_IV_LEN];
pub type BufferPlaintext2 = EdhocMessageBuffer;
pub type BufferPlaintext3 = EdhocMessageBuffer;
pub type BytesMac2 = [u8; MAC_LENGTH_2];
pub type BytesMac3 = [u8; MAC_LENGTH_3];
pub type BufferMessage1 = EdhocMessageBuffer;
pub type BufferMessage3 = EdhocMessageBuffer;
pub type BufferCiphertext2 = EdhocMessageBuffer;
pub type BufferCiphertext3 = EdhocMessageBuffer;
pub type BytesHashLen = [u8; SHA256_DIGEST_LEN];
pub type BytesP256ElemLen = [u8; P256_ELEM_LEN];
pub type BufferMessage2 = EdhocMessageBuffer;
pub type BytesMaxBuffer = [u8; MAX_BUFFER_LEN];
pub type BytesMaxContextBuffer = [u8; MAX_KDF_CONTEXT_LEN];
pub type BytesMaxInfoBuffer = [u8; MAX_INFO_LEN];
pub type BytesMaxLabelBuffeer = [u8; MAX_KDF_LABEL_LEN];
pub type BytesEncStructureLen = [u8; ENC_STRUCTURE_LEN];
pub type BytesMac = [u8; MAC_LENGTH];
pub type BytesEncodedVoucher = [u8; ENCODED_VOUCHER_LEN];
pub type EADMessageBuffer = EdhocMessageBuffer; #[repr(C)]
#[derive(PartialEq, Debug)]
pub enum EDHOCError {
    UnknownPeer = 1,
    MacVerificationFailed = 2,
    UnsupportedMethod = 3,
    UnsupportedCipherSuite = 4,
    ParsingError = 5,
    EadLabelTooLongError = 6,
    EadTooLongError = 7,
    EADError = 8,
    UnknownError = 9,
}
#[derive(Debug)]
#[repr(C)]
pub struct InitiatorStart {
    pub suites_i: BytesSuites,
    pub suites_i_len: usize,
    pub x: BytesP256ElemLen,   pub g_x: BytesP256ElemLen, }
#[derive(Debug)]
pub struct ResponderStart {
    pub y: BytesP256ElemLen,   pub g_y: BytesP256ElemLen, }
#[derive(Default, Debug)]
pub struct ProcessingM1 {
    pub y: BytesP256ElemLen,
    pub g_y: BytesP256ElemLen,
    pub c_i: u8,
    pub g_x: BytesP256ElemLen, pub h_message_1: BytesHashLen,
}
#[derive(Default, Clone, Debug)]
#[repr(C)]
pub struct WaitM2 {
    pub x: BytesP256ElemLen, pub h_message_1: BytesHashLen,
}
#[derive(Default, Debug)]
pub struct WaitM3 {
    pub y: BytesP256ElemLen, pub prk_3e2m: BytesHashLen,
    pub th_3: BytesHashLen,
}
#[derive(Debug, Default)]
#[repr(C)]
pub struct ProcessingM2 {
    pub mac_2: BytesMac2,
    pub prk_2e: BytesHashLen,
    pub th_2: BytesHashLen,
    pub x: BytesP256ElemLen,
    pub g_y: BytesP256ElemLen,
    pub plaintext_2: EdhocMessageBuffer,
    pub c_r: u8,
    pub ead_2: Option<EADItem>,
}
#[derive(Default, Debug)]
#[repr(C)]
pub struct ProcessedM2 {
    pub prk_3e2m: BytesHashLen,
    pub prk_4e3m: BytesHashLen,
    pub th_3: BytesHashLen,
}
#[derive(Default, Debug)]
pub struct ProcessingM3 {
    pub mac_3: BytesMac3,
    pub y: BytesP256ElemLen, pub prk_3e2m: BytesHashLen,
    pub th_3: BytesHashLen,
    pub plaintext_3: EdhocMessageBuffer,
    pub ead_3: Option<EADItem>,
}
#[derive(Debug)]
pub struct PreparingM3 {
    pub prk_3e2m: BytesHashLen,
    pub prk_4e3m: BytesHashLen,
    pub th_3: BytesHashLen,
    pub mac_3: BytesMac3,
}
#[derive(Default, Debug)]
#[repr(C)]
pub struct Completed {
    pub prk_out: BytesHashLen,
    pub prk_exporter: BytesHashLen,
}
#[cfg_attr(feature = "python-bindings", pyclass)]
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum CredentialTransfer {
    ByReference,
    ByValue,
}
#[derive(PartialEq, Debug)]
#[repr(C)]
pub enum MessageBufferError {
    BufferAlreadyFull,
    SliceTooLong,
}
#[repr(C)]
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct EdhocMessageBuffer {
    pub content: [u8; MAX_MESSAGE_SIZE_LEN],
    pub len: usize,
}
impl Default for EdhocMessageBuffer {
    fn default() -> Self {
        EdhocMessageBuffer {
            content: [0; MAX_MESSAGE_SIZE_LEN],
            len: 0,
        }
    }
}
impl EdhocMessageBuffer {
    pub fn new() -> Self {
        EdhocMessageBuffer {
            content: [0u8; MAX_MESSAGE_SIZE_LEN],
            len: 0,
        }
    }
    pub fn new_from_slice(slice: &[u8]) -> Result<Self, MessageBufferError> {
        let mut buffer = Self::new();
        if buffer.fill_with_slice(slice).is_ok() {
            Ok(buffer)
        } else {
            Err(MessageBufferError::SliceTooLong)
        }
    }
    pub fn get(self, index: usize) -> Option<u8> {
        self.content.get(index).copied()
    }
    pub fn push(&mut self, item: u8) -> Result<(), MessageBufferError> {
        if self.len < self.content.len() {
            self.content[self.len] = item;
            self.len += 1;
            Ok(())
        } else {
            Err(MessageBufferError::BufferAlreadyFull)
        }
    }
    pub fn get_slice(&self, start: usize, len: usize) -> Option<&[u8]> {
        self.content.get(start..start + len)
    }
    pub fn as_slice(&self) -> &[u8] {
        &self.content[0..self.len]
    }
    pub fn fill_with_slice(&mut self, slice: &[u8]) -> Result<(), MessageBufferError> {
        if slice.len() <= self.content.len() {
            self.len = slice.len();
            self.content[..self.len].copy_from_slice(slice);
            Ok(())
        } else {
            Err(MessageBufferError::SliceTooLong)
        }
    }
    pub fn extend_from_slice(&mut self, slice: &[u8]) -> Result<(), MessageBufferError> {
        if self.len + slice.len() <= self.content.len() {
            self.content[self.len..self.len + slice.len()].copy_from_slice(slice);
            self.len += slice.len();
            Ok(())
        } else {
            Err(MessageBufferError::SliceTooLong)
        }
    }
    pub fn from_hex(hex: &str) -> Self {
        let mut buffer = EdhocMessageBuffer::new();
        buffer.len = hex.len() / 2;
        for (i, chunk) in hex.as_bytes().chunks(2).enumerate() {
            let chunk_str = core::str::from_utf8(chunk).unwrap();
            buffer.content[i] = u8::from_str_radix(chunk_str, 16).unwrap();
        }
        buffer
    }
}
impl TryInto<EdhocMessageBuffer> for &[u8] {
    type Error = ();
    fn try_into(self) -> Result<EdhocMessageBuffer, Self::Error> {
        let mut buffer = [0u8; MAX_MESSAGE_SIZE_LEN];
        if self.len() <= buffer.len() {
            buffer[..self.len()].copy_from_slice(self);
            Ok(EdhocMessageBuffer {
                content: buffer,
                len: self.len(),
            })
        } else {
            Err(())
        }
    }
}
#[cfg_attr(feature = "python-bindings", pyclass)]
#[derive(Clone, Debug)]
pub struct EADItem {
    pub label: u8,
    pub is_critical: bool,
    pub value: Option<EdhocMessageBuffer>,
}
impl EADItem {
    pub fn new() -> Self {
        EADItem {
            label: 0,
            is_critical: false,
            value: None,
        }
    }
}
#[derive(Debug, Clone, Copy)]
pub enum IdCred<'a> {
    CompactKid(u8),
    FullCredential(&'a [u8]),
}
mod helpers {
    use super::*;
    pub fn encode_info(
        label: u8,
        context: &BytesMaxContextBuffer,
        context_len: usize,
        length: usize,
    ) -> (BytesMaxInfoBuffer, usize) {
        let mut info: BytesMaxInfoBuffer = [0x00; MAX_INFO_LEN];
        info[0] = label;
        let mut info_len = if context_len < 24 {
            info[1] = context_len as u8 | CBOR_MAJOR_BYTE_STRING;
            info[2..2 + context_len].copy_from_slice(&context[..context_len]);
            2 + context_len
        } else {
            info[1] = CBOR_BYTE_STRING;
            info[2] = context_len as u8;
            info[3..3 + context_len].copy_from_slice(&context[..context_len]);
            3 + context_len
        };
        info_len = if length < 24 {
            info[info_len] = length as u8;
            info_len + 1
        } else {
            info[info_len] = CBOR_UINT_1BYTE;
            info[info_len + 1] = length as u8;
            info_len + 2
        };
        (info, info_len)
    }
}
mod edhoc_parser {
    use super::*;
    pub fn parse_ead(buffer: &[u8]) -> Result<Option<EADItem>, EDHOCError> {
        if let Some((&label, tail)) = buffer.split_first() {
            let label_res = if CBORDecoder::is_u8(label) {
                Ok((label, false))
            } else if CBORDecoder::is_i8(label) {
                Ok((label - (CBOR_NEG_INT_1BYTE_START - 1), true))
            } else {
                Err(EDHOCError::ParsingError)
            };
            if let Ok((label, is_critical)) = label_res {
                let ead_value = if tail.len() > 0 {
                    let mut buffer = EdhocMessageBuffer::new();
                    buffer.fill_with_slice(tail).unwrap(); buffer.len = tail.len();
                    Some(buffer)
                } else {
                    None
                };
                let ead_item = Some(EADItem {
                    label,
                    is_critical,
                    value: ead_value,
                });
                Ok(ead_item)
            } else {
                Err(EDHOCError::ParsingError)
            }
        } else {
            Err(EDHOCError::ParsingError)
        }
    }
    pub fn parse_suites_i(
        mut decoder: CBORDecoder,
    ) -> Result<(BytesSuites, usize, CBORDecoder), EDHOCError> {
        let mut suites_i: BytesSuites = Default::default();
        if let Ok(curr) = decoder.current() {
            if CBOR_UINT_1BYTE_START == CBORDecoder::type_of(curr) {
                suites_i[0] = decoder.u8()?;
                let suites_i_len = 1;
                Ok((suites_i, suites_i_len, decoder))
            } else if CBOR_MAJOR_ARRAY == CBORDecoder::type_of(curr)
                && CBORDecoder::info_of(curr) >= 2
            {
                let suites_i_len = decoder.array()?;
                if suites_i_len <= suites_i.len() {
                    for i in 0..suites_i_len {
                        suites_i[i] = decoder.u8()?;
                    }
                    Ok((suites_i, suites_i_len, decoder))
                } else {
                    Err(EDHOCError::ParsingError)
                }
            } else {
                Err(EDHOCError::ParsingError)
            }
        } else {
            Err(EDHOCError::ParsingError)
        }
    }
    pub fn parse_message_1(
        rcvd_message_1: &BufferMessage1,
    ) -> Result<
        (
            u8,
            BytesSuites,
            usize,
            BytesP256ElemLen,
            u8,
            Option<EADItem>,
        ),
        EDHOCError,
    > {
        let mut decoder = CBORDecoder::new(rcvd_message_1.as_slice());
        let method = decoder.u8()?;
        if let Ok((suites_i, suites_i_len, mut decoder)) = parse_suites_i(decoder) {
            let mut g_x: BytesP256ElemLen = [0x00; P256_ELEM_LEN];
            g_x.copy_from_slice(decoder.bytes_sized(P256_ELEM_LEN)?);
            let c_i = decoder.int_raw()?;
            if rcvd_message_1.len > decoder.position() {
                let ead_res = parse_ead(decoder.remaining_buffer()?);
                if let Ok(ead_1) = ead_res {
                    Ok((method, suites_i, suites_i_len, g_x, c_i, ead_1))
                } else {
                    Err(ead_res.unwrap_err())
                }
            } else if decoder.finished() {
                Ok((method, suites_i, suites_i_len, g_x, c_i, None))
            } else {
                Err(EDHOCError::ParsingError)
            }
        } else {
            Err(EDHOCError::ParsingError)
        }
    }
    pub fn parse_message_2(
        rcvd_message_2: &BufferMessage2,
    ) -> Result<(BytesP256ElemLen, BufferCiphertext2), EDHOCError> {
        let mut ciphertext_2: BufferCiphertext2 = BufferCiphertext2::new();
        let mut decoder = CBORDecoder::new(rcvd_message_2.as_slice());
        let decoded = decoder.bytes()?;
        if decoder.finished() {
            if let Some(key) = decoded.get(0..P256_ELEM_LEN) {
                let mut g_y: BytesP256ElemLen = [0x00; P256_ELEM_LEN];
                g_y.copy_from_slice(key);
                if let Some(c2) = decoded.get(P256_ELEM_LEN..) {
                    if ciphertext_2.fill_with_slice(c2).is_ok() {
                        Ok((g_y, ciphertext_2))
                    } else {
                        Err(EDHOCError::ParsingError)
                    }
                } else {
                    Err(EDHOCError::ParsingError)
                }
            } else {
                Err(EDHOCError::ParsingError)
            }
        } else {
            Err(EDHOCError::ParsingError)
        }
    }
    pub fn decode_plaintext_2(
        plaintext_2: &BufferCiphertext2,
    ) -> Result<(u8, IdCred, BytesMac2, Option<EADItem>), EDHOCError> {
        let mut mac_2: BytesMac2 = [0x00; MAC_LENGTH_2];
        let mut decoder = CBORDecoder::new(plaintext_2.as_slice());
        let c_r = decoder.int_raw()?;
        let id_cred_r = if CBOR_MAJOR_BYTE_STRING == CBORDecoder::type_of(decoder.current()?)
            && CBORDecoder::info_of(decoder.current()?) > 1
        {
            IdCred::FullCredential(decoder.bytes()?)
        } else {
            IdCred::CompactKid(decoder.int_raw()?)
        };
        mac_2[..].copy_from_slice(decoder.bytes_sized(MAC_LENGTH_2)?);
        if plaintext_2.len > decoder.position() {
            let ead_res = parse_ead(decoder.remaining_buffer()?);
            if let Ok(ead_2) = ead_res {
                Ok((c_r, id_cred_r, mac_2, ead_2))
            } else {
                Err(ead_res.unwrap_err())
            }
        } else if decoder.finished() {
            Ok((c_r, id_cred_r, mac_2, None))
        } else {
            Err(EDHOCError::ParsingError)
        }
    }
    pub fn decode_plaintext_3(
        plaintext_3: &BufferPlaintext3,
    ) -> Result<(IdCred, BytesMac3, Option<EADItem>), EDHOCError> {
        let mut mac_3: BytesMac3 = [0x00; MAC_LENGTH_3];
        let mut decoder = CBORDecoder::new(plaintext_3.as_slice());
        let id_cred_i = if CBOR_MAJOR_BYTE_STRING == CBORDecoder::type_of(decoder.current()?)
            && CBORDecoder::info_of(decoder.current()?) > 1
        {
            IdCred::FullCredential(decoder.bytes()?)
        } else {
            IdCred::CompactKid(decoder.int_raw()?)
        };
        mac_3[..].copy_from_slice(decoder.bytes_sized(MAC_LENGTH_3)?);
        if plaintext_3.len > decoder.position() {
            let ead_res = parse_ead(decoder.remaining_buffer()?);
            if let Ok(ead_3) = ead_res {
                Ok((id_cred_i, mac_3, ead_3))
            } else {
                Err(ead_res.unwrap_err())
            }
        } else if decoder.finished() {
            Ok((id_cred_i, mac_3, None))
        } else {
            Err(EDHOCError::ParsingError)
        }
    }
}
mod cbor_decoder {
    use super::*;
    #[derive(Debug)]
    pub enum CBORError {
        DecodingError,
    }
    impl From<CBORError> for EDHOCError {
        fn from(error: CBORError) -> Self {
            match error {
                CBORError::DecodingError => EDHOCError::ParsingError,
            }
        }
    }
    #[derive(Debug)]
    pub struct CBORDecoder<'a> {
        buf: &'a [u8],
        pos: usize,
    }
    impl<'a> CBORDecoder<'a> {
        pub fn new(bytes: &'a [u8]) -> Self {
            CBORDecoder { buf: bytes, pos: 0 }
        }
        fn read(&mut self) -> Result<u8, CBORError> {
            if let Some(b) = self.buf.get(self.pos) {
                self.pos += 1;
                Ok(*b)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        fn read_slice(&mut self, n: usize) -> Result<&'a [u8], CBORError> {
            if let Some(b) = self
                .pos
                .checked_add(n)
                .and_then(|end| self.buf.get(self.pos..end))
            {
                self.pos += n;
                Ok(b)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn position(&self) -> usize {
            self.pos
        }
        pub fn finished(&self) -> bool {
            self.pos == self.buf.len()
        }
        pub fn ensure_finished(&self) -> Result<(), CBORError> {
            if self.finished() {
                Ok(())
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn remaining_buffer(&self) -> Result<&[u8], CBORError> {
            if let Some(buffer) = self.buf.get(self.pos..) {
                Ok(buffer)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn current(&self) -> Result<u8, CBORError> {
            if let Some(b) = self.buf.get(self.pos) {
                Ok(*b)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn u8(&mut self) -> Result<u8, CBORError> {
            let n = self.read()?;
            if (0..=0x17).contains(&n) {
                Ok(n)
            } else if 0x18 == n {
                self.read()
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn i8(&mut self) -> Result<i8, CBORError> {
            let n = self.read()?;
            if (0..=0x17).contains(&n) {
                Ok(n as i8)
            } else if (0x20..=0x37).contains(&n) {
                Ok(-1 - (n - 0x20) as i8)
            } else if 0x18 == n {
                Ok(self.read()? as i8)
            } else if 0x38 == n {
                Ok(-1 - (self.read()? - 0x20) as i8)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn int_raw(&mut self) -> Result<u8, CBORError> {
            let n = self.read()?;
            if (0..=0x17).contains(&n) || (0x20..=0x37).contains(&n) {
                Ok(n)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn str(&mut self) -> Result<&'a [u8], CBORError> {
            let b = self.read()?;
            if CBOR_MAJOR_TEXT_STRING != Self::type_of(b) || Self::info_of(b) == 31 {
                Err(CBORError::DecodingError)
            } else {
                let n = self.as_usize(Self::info_of(b))?;
                self.read_slice(n)
            }
        }
        pub fn bytes(&mut self) -> Result<&'a [u8], CBORError> {
            let b = self.read()?;
            if CBOR_MAJOR_BYTE_STRING != Self::type_of(b) || Self::info_of(b) == 31 {
                Err(CBORError::DecodingError)
            } else {
                let n = self.as_usize(Self::info_of(b))?;
                self.read_slice(n)
            }
        }
        pub fn bytes_sized(&mut self, expected_size: usize) -> Result<&'a [u8], CBORError> {
            let res = self.bytes()?;
            if res.len() == expected_size {
                Ok(res)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn array(&mut self) -> Result<usize, CBORError> {
            let b = self.read()?;
            if CBOR_MAJOR_ARRAY != Self::type_of(b) {
                Err(CBORError::DecodingError)
            } else {
                match Self::info_of(b) {
                    31 => Err(CBORError::DecodingError), n => Ok(self.as_usize(n)?),
                }
            }
        }
        pub fn as_usize(&mut self, b: u8) -> Result<usize, CBORError> {
            if (0..=0x17).contains(&b) {
                Ok(usize::from(b))
            } else if 0x18 == b {
                self.read().map(usize::from)
            } else {
                Err(CBORError::DecodingError)
            }
        }
        pub fn type_of(b: u8) -> u8 {
            b & 0b111_00000
        }
        pub fn info_of(b: u8) -> u8 {
            b & 0b000_11111
        }
        pub fn is_u8(byte: u8) -> bool {
            byte >= CBOR_UINT_1BYTE_START && byte <= CBOR_UINT_1BYTE_END
        }
        pub fn is_i8(byte: u8) -> bool {
            byte >= CBOR_NEG_INT_1BYTE_START && byte <= CBOR_NEG_INT_1BYTE_END
        }
    }
}
#[cfg(test)]
mod test_cbor_decoder {
    use super::cbor_decoder::*;
    #[test]
    fn test_cbor_decoder() {
        let input = [0x01, 0x20, 0x62, 0x68, 0x69, 0x42, 0xFE, 0xFE];
        let mut decoder = CBORDecoder::new(&input);
        assert_eq!(1, decoder.u8().unwrap());
        assert_eq!(-1, decoder.i8().unwrap());
        assert_eq!([0x68, 0x69], decoder.str().unwrap()); assert_eq!([0xFE, 0xFE], decoder.bytes().unwrap());
    }
}