msgpck 0.2.8

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

impl MsgPack for u8 {
    fn pack(&self) -> impl Iterator<Item = Piece<'_>> {
        pack_u64(u64::from(*self)).pieces()
    }
}

impl MsgPack for u16 {
    fn pack(&self) -> impl Iterator<Item = Piece<'_>> {
        pack_u64(u64::from(*self)).pieces()
    }
}

impl MsgPack for u32 {
    fn pack(&self) -> impl Iterator<Item = Piece<'_>> {
        pack_u64(u64::from(*self)).pieces()
    }
}

impl MsgPack for u64 {
    fn pack(&self) -> impl Iterator<Item = Piece<'_>> {
        pack_u64(*self).pieces()
    }
}

impl<'buf> MsgUnpack<'buf> for u8 {
    fn unpack(bytes: &mut &'buf [u8]) -> Result<Self, UnpackErr>
    where
        Self: Sized,
    {
        let n = unpack_u64(bytes)?;
        Ok(n.try_into()?)
    }
}

impl<'buf> MsgUnpack<'buf> for u16 {
    fn unpack(bytes: &mut &'buf [u8]) -> Result<Self, UnpackErr>
    where
        Self: Sized,
    {
        let n = unpack_u64(bytes)?;
        Ok(n.try_into()?)
    }
}

impl<'buf> MsgUnpack<'buf> for u32 {
    fn unpack(bytes: &mut &'buf [u8]) -> Result<Self, UnpackErr>
    where
        Self: Sized,
    {
        let n = unpack_u64(bytes)?;
        Ok(n.try_into()?)
    }
}

impl<'buf> MsgUnpack<'buf> for u64 {
    fn unpack(bytes: &mut &'buf [u8]) -> Result<Self, UnpackErr>
    where
        Self: Sized,
    {
        unpack_u64(bytes)
    }
}

pub fn unpack_u64(bytes: &mut &[u8]) -> Result<u64, UnpackErr> {
    let &[b] = slice_take(bytes)?;

    Ok(match Marker::from_u8(b) {
        Marker::FixPos(n) => n.into(),
        Marker::U8 => slice_take::<u8, 1>(bytes)?[0].into(),
        Marker::U16 => u16::from_be_bytes(*slice_take(bytes)?).into(),
        Marker::U32 => u32::from_be_bytes(*slice_take(bytes)?).into(),
        Marker::U64 => u64::from_be_bytes(*slice_take(bytes)?),
        m => return Err(UnpackErr::WrongMarker(m)),
    })
}

pub const fn pack_u64<'a>(n: u64) -> Pair<'a> {
    match n {
        ..=0x7f => Pair(Piece::from_marker(Marker::FixPos(n as u8)), None),
        ..=0xff => Pair(
            Piece::from_marker(Marker::U8),
            Some(Piece::from_u8(n as u8)),
        ),
        ..=0xffff => Pair(
            Piece::from_marker(Marker::U16),
            Some(Piece::from_u16(n as u16)),
        ),
        ..=0xffff_ffff => Pair(
            Piece::from_marker(Marker::U32),
            Some(Piece::from_u32(n as u32)),
        ),
        _ => Pair(Piece::from_marker(Marker::U64), Some(Piece::from_u64(n))),
    }
}