use alloc::string::String;
use bytes::BufMut;
use crate::{format::Format, Packable};
pub fn pack_bytes_slice_len<T: BufMut>(buf: &mut T, slice: &[u8]) -> usize {
if slice.len() <= u8::MAX as usize {
buf.put_slice(&[Format::BIN8, slice.len() as u8]);
2
} else if slice.len() <= u16::MAX as usize {
let mut s = [0u8; 3];
s[0] = Format::BIN16;
s[1..].copy_from_slice(&(slice.len() as u16).to_be_bytes());
buf.put_slice(&s);
3
} else if slice.len() <= u32::MAX as usize {
let mut s = [0u8; 5];
s[0] = Format::BIN32;
s[1..].copy_from_slice(&(slice.len() as u32).to_be_bytes());
buf.put_slice(&s);
5
} else {
#[cfg(feature = "strict")]
panic!("strict serialization enabled; the buffer is too large");
#[allow(unreachable_code)]
return 0;
}
}
pub fn pack_bytes<T: BufMut>(buf: &mut T, slice: &[u8]) -> usize {
let n = pack_bytes_slice_len(buf, slice);
buf.put_slice(slice);
n + slice.len()
}
pub fn pack_bytes_option<T: BufMut>(buf: &mut T, v: Option<&[u8]>) -> usize {
match v {
None => {
buf.put_u8(crate::format::Format::NIL);
1
}
Some(slice) => pack_bytes(buf, slice),
}
}
impl Packable for str {
fn pack<T>(&self, buf: &mut T) -> usize
where
T: BufMut,
{
let n = if self.len() <= 31 {
buf.put_u8((self.len() as u8 & 0x1f) | 0xa0);
1
} else if self.len() <= u8::MAX as usize {
buf.put_slice(&[Format::STR8, self.len() as u8]);
2
} else if self.len() <= u16::MAX as usize {
let mut s = [0u8; 3];
s[0] = Format::STR16;
s[1..].copy_from_slice(&(self.len() as u16).to_be_bytes());
buf.put_slice(&s);
3
} else if self.len() <= u32::MAX as usize {
let mut s = [0u8; 5];
s[0] = Format::STR32;
s[1..].copy_from_slice(&(self.len() as u32).to_be_bytes());
buf.put_slice(&s);
5
} else {
#[cfg(feature = "strict")]
panic!("strict serialization enabled; the buffer is too large");
#[allow(unreachable_code)]
return 0;
};
buf.put_slice(self.as_bytes());
n + self.len()
}
}
impl Packable for String {
fn pack<T>(&self, buf: &mut T) -> usize
where
T: BufMut,
{
self.as_str().pack(buf)
}
}