use bytes::Buf;
use bytes::BufMut;
use bytes::Bytes;
use bytes::BytesMut;
pub struct FlexBuf {
cap: usize,
len: usize,
buf: BytesMut,
frozen: Option<Bytes>,
}
impl FlexBuf {
pub fn new(cap: usize) -> Self {
FlexBuf {
cap,
len: 0,
buf: BytesMut::with_capacity(cap),
frozen: None,
}
}
pub fn put(&mut self, bs: &[u8]) -> usize {
if self.frozen.is_some() {
return 0;
}
let n = (self.cap - self.len).min(bs.len());
self.buf.put_slice(&bs[..n]);
self.len += n;
if self.len >= self.cap {
let frozen = self.buf.split();
self.len = 0;
self.frozen = Some(frozen.freeze());
}
n
}
pub fn freeze(&mut self) {
if self.len == 0 {
return;
}
let frozen = self.buf.split();
self.len = 0;
self.frozen = Some(frozen.freeze());
}
pub fn get(&mut self) -> Option<Bytes> {
self.frozen.clone()
}
pub fn advance(&mut self, cnt: usize) {
debug_assert!(self.len == 0, "The buffer must be empty during advance");
let Some(bs) = self.frozen.as_mut() else {
unreachable!("It must be a bug to advance on not frozen buffer")
};
bs.advance(cnt);
if bs.is_empty() {
self.clean()
}
}
#[inline]
pub fn clean(&mut self) {
self.frozen = None;
self.buf.reserve(self.cap);
}
}