use bytes::{Buf, BufMut, Bytes, BytesMut};
const HEADER_LEN: usize = 5;
pub fn frame(message: &[u8]) -> Bytes {
let mut buf = BytesMut::with_capacity(HEADER_LEN + message.len());
buf.put_u8(0); buf.put_u32(message.len() as u32);
buf.put_slice(message);
buf.freeze()
}
#[derive(Default)]
pub struct Deframer {
buf: BytesMut,
}
impl Deframer {
pub fn new() -> Self {
Self::default()
}
pub fn push(&mut self, chunk: &[u8]) {
self.buf.put_slice(chunk);
}
pub fn next_message(&mut self) -> Option<Bytes> {
if self.buf.len() < HEADER_LEN {
return None;
}
let len = u32::from_be_bytes([self.buf[1], self.buf[2], self.buf[3], self.buf[4]]) as usize;
if self.buf.len() < HEADER_LEN + len {
return None;
}
self.buf.advance(HEADER_LEN);
Some(self.buf.split_to(len).freeze())
}
pub fn is_empty(&self) -> bool {
self.buf.is_empty()
}
}
pub fn deframe_all(body: &[u8]) -> Vec<Bytes> {
let mut d = Deframer::new();
d.push(body);
let mut out = Vec::new();
while let Some(m) = d.next_message() {
out.push(m);
}
out
}