use bytemuck::Pod;
use std::convert::TryInto;
pub fn write_to_vec<T: Pod>(val: T, out: &mut Vec<u8>) {
let len = out.len();
let size = std::mem::size_of::<T>();
out.resize(len + size, 0);
unsafe {
let ptr = out.as_mut_ptr().add(len);
std::ptr::write_unaligned(ptr as *mut T, val);
}
}
pub fn read_from_bytes<T: Pod>(bts: &[u8]) -> Option<(usize, T)> {
let size = std::mem::size_of::<T>();
if bts.len() < size {
return None;
}
unsafe { Some((size, std::ptr::read_unaligned(bts.as_ptr() as *const T))) }
}
pub fn encode_str(s: &str, out: &mut Vec<u8>) {
let len: u32 = s
.len()
.try_into()
.expect("Failed to cast string len to u32");
write_to_vec(len, out);
out.extend_from_slice(s.as_bytes());
}
pub fn decode_str(bts: &[u8]) -> Option<(usize, &str)> {
let (sl, len): (_, u32) = read_from_bytes(bts)?;
if bts.len() - sl < len as usize {
return None;
}
let bts = &bts[sl..sl + len as usize];
Some((sl + len as usize, std::str::from_utf8(bts).ok()?))
}