stak_device/device/
fixed_buffer.rs

1use crate::{BufferError, Device};
2use winter_maybe_async::maybe_async;
3
4/// A fixed buffer device.
5#[derive(Debug)]
6pub struct FixedBufferDevice<'a, const O: usize, const E: usize> {
7    input: &'a [u8],
8    output: [u8; O],
9    error: [u8; E],
10    input_index: usize,
11    output_index: usize,
12    error_index: usize,
13}
14
15impl<'a, const O: usize, const E: usize> FixedBufferDevice<'a, O, E> {
16    /// Creates a device.
17    pub const fn new(input: &'a [u8]) -> Self {
18        Self {
19            input,
20            output: [0; O],
21            error: [0; E],
22            input_index: 0,
23            output_index: 0,
24            error_index: 0,
25        }
26    }
27
28    /// Returns a reference to standard output.
29    pub fn output(&self) -> &[u8] {
30        &self.output[..self.output_index]
31    }
32
33    /// Returns a reference to standard error.
34    pub fn error(&self) -> &[u8] {
35        &self.error[..self.error_index]
36    }
37}
38
39impl<const O: usize, const E: usize> Device for FixedBufferDevice<'_, O, E> {
40    type Error = BufferError;
41
42    #[maybe_async]
43    fn read(&mut self) -> Result<Option<u8>, Self::Error> {
44        Ok(if let Some(&byte) = self.input.get(self.input_index) {
45            self.input_index += 1;
46
47            Some(byte)
48        } else {
49            None
50        })
51    }
52
53    #[maybe_async]
54    fn write(&mut self, byte: u8) -> Result<(), Self::Error> {
55        let Some(output) = self.output.get_mut(self.output_index) else {
56            return Err(BufferError::Write);
57        };
58
59        *output = byte;
60        self.output_index += 1;
61
62        Ok(())
63    }
64
65    #[maybe_async]
66    fn write_error(&mut self, byte: u8) -> Result<(), Self::Error> {
67        let Some(error) = self.error.get_mut(self.error_index) else {
68            return Err(BufferError::Write);
69        };
70
71        *error = byte;
72        self.error_index += 1;
73
74        Ok(())
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81    use stak_util::block_on;
82
83    #[test]
84    fn read() {
85        let mut device = FixedBufferDevice::<0, 0>::new(&[42]);
86
87        assert_eq!(block_on!(device.read()), Ok(Some(42)));
88        assert_eq!(block_on!(device.read()), Ok(None));
89    }
90
91    #[test]
92    fn write() {
93        let mut device = FixedBufferDevice::<1, 0>::new(&[]);
94
95        assert_eq!(block_on!(device.write(42)), Ok(()));
96        assert_eq!(block_on!(device.write(42)), Err(BufferError::Write));
97        assert_eq!(device.output(), [42]);
98    }
99
100    #[test]
101    fn write_error() {
102        let mut device = FixedBufferDevice::<0, 1>::new(&[]);
103
104        assert_eq!(block_on!(device.write_error(42)), Ok(()));
105        assert_eq!(block_on!(device.write_error(42)), Err(BufferError::Write));
106        assert_eq!(device.error(), [42]);
107    }
108}