Skip to content
Snippets Groups Projects
buffer.rs 1.54 KiB
Newer Older
Stephen D's avatar
wip
Stephen D committed
use core::{borrow::Borrow, ops::Deref};

pub(crate) struct BufferOverflow;

pub(crate) struct Buffer<'a, const N: usize> {
    data: &'a mut [u8; N],
    i: usize,
}

impl<'a, const N: usize> Buffer<'a, N> {
    pub fn new(data: &'a mut [u8; N], i: usize) -> Self {
        Self { data, i }
    }

    /*pub fn as_slice(&self) -> &'a [u8] {
            &self.data[..self.i]
        }

        pub fn as_slice_mut(&mut self) -> &'a [u8] {
            &mut self.data[..self.i]
    }*/

    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 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 pop(&mut self) -> Option<u8> {
        if self.i == 0 {
            return None;
        }

        self.i -= 1;

        Some(self.data[self.i])
    }
}

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]
    }
}