use std::fmt;
pub(crate) struct Buffer {
inner: Box<[u8]>,
begin: usize,
end: usize,
}
impl fmt::Debug for Buffer {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("Buffer")
.field("len", &self.len())
.finish()
}
}
impl Buffer {
pub(crate) fn new(capacity: usize) -> Self {
Self {
inner: vec![0; capacity].into_boxed_slice(),
begin: 0,
end: 0,
}
}
pub(crate) fn len(&self) -> usize {
self.end - self.begin
}
pub(crate) fn capacity(&self) -> usize {
self.inner.len() - self.end
}
pub(crate) fn push(&mut self, buf: &[u8]) -> usize {
let n = std::cmp::min(self.capacity(), buf.len());
self.inner[self.end..self.end + n].copy_from_slice(&buf[..n]);
self.end += n;
n
}
pub(crate) fn as_mut_capacity(&mut self) -> &mut [u8] {
&mut self.inner[self.end..]
}
pub(crate) fn extend(&mut self, n: usize) {
debug_assert!(self.end + n <= self.inner.len());
self.end += n;
}
pub(crate) fn as_slice(&self) -> &[u8] {
&self.inner[self.begin..self.end]
}
pub(crate) fn take(&mut self, n: usize) {
debug_assert!(self.begin + n <= self.end);
self.begin += n;
}
pub(crate) fn prefix<const N: usize>(&self) -> [u8; N] {
debug_assert!(self.begin + N <= self.end);
self.inner[self.begin..self.begin + N].try_into().unwrap()
}
pub(crate) fn set_prefix<const N: usize>(&mut self, prefix: [u8; N]) {
*<&mut [u8; N]>::try_from(&mut self.inner[self.end..self.end + N]).unwrap() = prefix;
}
pub(crate) fn shift(&mut self) {
self.inner.copy_within(self.begin..self.end, 0);
self.end -= self.begin;
self.begin = 0;
}
pub(crate) fn reset(&mut self) {
self.begin = 0;
self.end = 0;
}
}