Newer
Older
#[derive(Debug)]
pub struct BufferOverflow;
#[derive(Debug)]
pub struct Buffer<'a, const N: usize> {
data: &'a mut [u8; N],
i: usize,
}
impl<'a, const N: usize> Buffer<'a, N> {
/// Constructs a new `Buffer`.
/// `data` is the backing array.
/// `i` is the number of elements in `data` that contain data (and should thus be exposed by `Buffer`)
pub fn new_full(data: &'a mut [u8; N]) -> Self {
let i = data.len();
Self::new(data, i)
}
pub fn new_empty(data: &'a mut [u8; N]) -> Self {
Self::new(data, 0)
}
pub const fn remaining_capacity(&self) -> usize {
N - self.i
}
pub fn try_push(&mut self, v: u8) -> Result<(), BufferOverflow> {
if self.i == N {
return Err(BufferOverflow);
}
self.data[self.i] = v;
self.i += 1;
Ok(())
}
pub fn push(&mut self, v: u8) {
self.try_push(v).unwrap();
}
pub fn try_extend_from_slice(&mut self, other: &[u8]) -> Result<(), BufferOverflow> {
if self.remaining_capacity() < other.len() {
return Err(BufferOverflow);
}
self.data[self.i..(self.i + other.len())].copy_from_slice(other);
self.i += other.len();
Ok(())
}
pub fn extend(&mut self, other: &[u8]) {
self.try_extend_from_slice(other).unwrap();
}
pub fn pop(&mut self) -> Option<u8> {
if self.i == 0 {
return None;
}
self.i -= 1;
Some(self.data[self.i])
}
pub fn truncate(&mut self, new_len: usize) {
assert!(self.i >= new_len);
self.i = new_len;
}
pub fn drain(&mut self, start: usize, end: usize) {
assert!(end >= start);
assert!(end <= self.i);
let delta = end - start;
let surplus = self.len() - end;
for i in start..(start + surplus) {
self[i] = self[i + delta];
}
self.i -= delta;
}
pub fn clone_backing<'b>(&self, buf: &'b mut [u8; N]) -> Buffer<'b, N> {
let mut out = Buffer::new_empty(buf);
out.extend(self);
out
}
}
impl<'a, const N: usize> From<&'a mut [u8; N]> for Buffer<'a, N> {
fn from(data: &'a mut [u8; N]) -> Self {
Self { data, i: 0 }
}
}
impl<'a, const N: usize> Deref for Buffer<'a, N> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.data[..self.i]
}
}