ham_cats/
buffer.rs

1use core::ops::{Deref, DerefMut};
2
3#[derive(Debug)]
4pub struct BufferOverflow;
5
6#[derive(Debug)]
7pub struct Buffer<'a, const N: usize, T = u8> {
8    data: &'a mut [T; N],
9    i: usize,
10}
11
12impl<'a, const N: usize, T: Copy> Buffer<'a, N, T> {
13    /// Constructs a new `Buffer`.
14    /// `data` is the backing array.
15    /// `i` is the number of elements in `data` that contain data (and should thus be exposed by `Buffer`)
16    pub fn new(data: &'a mut [T; N], i: usize) -> Self {
17        assert!(i <= data.len());
18
19        Self { data, i }
20    }
21
22    pub fn new_full(data: &'a mut [T; N]) -> Self {
23        let i = data.len();
24
25        Self::new(data, i)
26    }
27
28    pub fn new_empty(data: &'a mut [T; N]) -> Self {
29        Self::new(data, 0)
30    }
31
32    pub const fn remaining_capacity(&self) -> usize {
33        N - self.i
34    }
35
36    pub fn try_push(&mut self, v: T) -> Result<(), BufferOverflow> {
37        if self.i == N {
38            return Err(BufferOverflow);
39        }
40
41        self.data[self.i] = v;
42        self.i += 1;
43
44        Ok(())
45    }
46
47    pub fn push(&mut self, v: T) {
48        self.try_push(v).unwrap();
49    }
50
51    pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), BufferOverflow> {
52        if self.remaining_capacity() < other.len() {
53            return Err(BufferOverflow);
54        }
55
56        self.data[self.i..(self.i + other.len())].copy_from_slice(other);
57        self.i += other.len();
58
59        Ok(())
60    }
61
62    pub fn extend(&mut self, other: &[T]) {
63        self.try_extend_from_slice(other).unwrap();
64    }
65
66    pub fn pop(&mut self) -> Option<T> {
67        if self.i == 0 {
68            return None;
69        }
70
71        self.i -= 1;
72
73        Some(self.data[self.i])
74    }
75
76    pub fn truncate(&mut self, new_len: usize) {
77        assert!(self.i >= new_len);
78
79        self.i = new_len;
80    }
81
82    pub fn drain(&mut self, start: usize, end: usize) {
83        assert!(end >= start);
84        assert!(end <= self.i);
85        let delta = end - start;
86        let surplus = self.len() - end;
87
88        for i in start..(start + surplus) {
89            self[i] = self[i + delta];
90        }
91
92        self.i -= delta;
93    }
94
95    pub fn clone_backing<'b>(&self, buf: &'b mut [T; N]) -> Buffer<'b, N, T> {
96        let mut out = Buffer::new_empty(buf);
97
98        out.extend(self);
99
100        out
101    }
102}
103
104impl<'a, const N: usize, T> From<&'a mut [T; N]> for Buffer<'a, N, T> {
105    fn from(data: &'a mut [T; N]) -> Self {
106        Self { data, i: 0 }
107    }
108}
109
110impl<const N: usize, T> Deref for Buffer<'_, N, T> {
111    type Target = [T];
112
113    fn deref(&self) -> &Self::Target {
114        &self.data[..self.i]
115    }
116}
117
118impl<const N: usize, T> DerefMut for Buffer<'_, N, T> {
119    fn deref_mut(&mut self) -> &mut [T] {
120        &mut self.data[..self.i]
121    }
122}