msgpck 0.2.8

A no-std and async compatible msgpck de/serializer
Documentation
use crate::{marker::Marker, util::slice_take, MsgPack, MsgUnpack, Piece, UnpackErr};

impl MsgPack for [u8] {
    fn pack(&self) -> impl Iterator<Item = Piece<'_>> {
        let marker_piece;
        let len_piece;

        match self.len() {
            ..=0xff => {
                marker_piece = Marker::Bin8.into();
                len_piece = (self.len() as u8).into();
            }
            ..=0xffff => {
                marker_piece = Marker::Bin16.into();
                len_piece = (self.len() as u16).into();
            }
            _ => {
                marker_piece = Marker::Bin32.into();
                len_piece = (self.len() as u32).into();
            }
        }

        [marker_piece, len_piece, Piece::Bytes(self)].into_iter()
    }
}

impl<'buf> MsgUnpack<'buf> for &'buf [u8] {
    fn unpack(bytes: &mut &'buf [u8]) -> Result<Self, UnpackErr>
    where
        Self: Sized,
    {
        let &[b] = slice_take(bytes)?;
        let len: usize = match Marker::from_u8(b) {
            Marker::Bin8 => slice_take::<_, 1>(bytes)?[0].into(),
            Marker::Bin16 => u16::from_be_bytes(*slice_take(bytes)?).into(),
            Marker::Bin32 => u32::from_be_bytes(*slice_take(bytes)?).try_into()?,
            m => return Err(UnpackErr::WrongMarker(m)),
        };

        if len > bytes.len() {
            return Err(UnpackErr::UnexpectedEof);
        }

        let (bin, rest) = bytes.split_at(len);
        *bytes = rest;

        Ok(bin)
    }
}