1use crate::{marker::Marker, util::slice_take, MsgPack, MsgUnpack, Piece, UnpackErr};
2
3impl MsgPack for [u8] {
4 fn pack(&self) -> impl Iterator<Item = Piece<'_>> {
5 let marker_piece;
6 let len_piece;
7
8 match self.len() {
9 ..=0xff => {
10 marker_piece = Marker::Bin8.into();
11 len_piece = (self.len() as u8).into();
12 }
13 ..=0xffff => {
14 marker_piece = Marker::Bin16.into();
15 len_piece = (self.len() as u16).into();
16 }
17 _ => {
18 marker_piece = Marker::Bin32.into();
19 len_piece = (self.len() as u32).into();
20 }
21 }
22
23 [marker_piece, len_piece, Piece::Bytes(self)].into_iter()
24 }
25}
26
27impl<'buf> MsgUnpack<'buf> for &'buf [u8] {
28 fn unpack(bytes: &mut &'buf [u8]) -> Result<Self, UnpackErr>
29 where
30 Self: Sized,
31 {
32 let &[b] = slice_take(bytes)?;
33 let len: usize = match Marker::from_u8(b) {
34 Marker::Bin8 => slice_take::<_, 1>(bytes)?[0].into(),
35 Marker::Bin16 => u16::from_be_bytes(*slice_take(bytes)?).into(),
36 Marker::Bin32 => u32::from_be_bytes(*slice_take(bytes)?).try_into()?,
37 m => return Err(UnpackErr::WrongMarker(m)),
38 };
39
40 if len > bytes.len() {
41 return Err(UnpackErr::UnexpectedEof);
42 }
43
44 let (bin, rest) = bytes.split_at(len);
45 *bytes = rest;
46
47 Ok(bin)
48 }
49}