use core::fmt;
use core::ops::{Deref, DerefMut};
#[derive(Debug, PartialEq)]
pub struct CapacityError;
pub struct Buffer<const CAP: usize> {
bytes: [u8; CAP],
len: usize,
}
impl<const CAP: usize> Default for Buffer<CAP> {
fn default() -> Self {
Self::new()
}
}
impl<const CAP: usize> Buffer<CAP> {
#[must_use]
pub const fn new() -> Self {
Self {
bytes: [0; CAP],
len: 0,
}
}
#[must_use]
pub const fn len(&self) -> usize {
self.len
}
#[must_use]
#[allow(clippy::unused_self)]
pub const fn capacity(&self) -> usize {
CAP
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn clear(&mut self) {
self.len = 0;
}
pub fn push(&mut self, value: u8) -> Result<(), CapacityError> {
if self.len < CAP {
self.bytes[self.len] = value;
self.len += 1;
Ok(())
} else {
Err(CapacityError)
}
}
pub fn extend_from_slice(&mut self, slice: &[u8]) -> Result<(), CapacityError> {
if self.len + slice.len() > CAP {
return Err(CapacityError);
}
let end = self.len + slice.len();
self.bytes[self.len..end].copy_from_slice(slice);
self.len = end;
Ok(())
}
}
impl<const CAP: usize> fmt::Write for Buffer<CAP> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.extend_from_slice(s.as_bytes()).map_err(|_| fmt::Error)
}
}
impl<const CAP: usize> Deref for Buffer<CAP> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.bytes[0..self.len]
}
}
impl<const CAP: usize> DerefMut for Buffer<CAP> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.bytes[0..self.len]
}
}
impl<const CAP: usize> AsRef<[u8]> for Buffer<CAP> {
fn as_ref(&self) -> &[u8] {
&self.bytes[0..self.len]
}
}
impl<const CAP: usize, T: ?Sized> PartialEq<T> for Buffer<CAP>
where
T: AsRef<[u8]>,
{
fn eq(&self, other: &T) -> bool {
self.as_ref() == other.as_ref()
}
}
impl<const CAP: usize> Eq for Buffer<CAP> {}