embytes_buffer/
read.rs

1use core::{cell::Cell, ops::Deref};
2
3use crate::Buffer;
4
5/// A Reader to read from a buffer like from a byte slice
6pub trait BufferReader: Deref<Target = [u8]> {
7
8    /// Tells the reader that `n` bytes were read
9    fn add_bytes_read(&self, n: usize);
10}
11
12/// An implementation of [`BufferReader`] for [`Buffer`]
13pub struct Reader <'a, T: AsMut<[u8]> + AsRef<[u8]>> {
14    buffer: &'a mut Buffer<T>,
15    bytes_read: Cell<usize>,
16    max_bytes: Option<usize>
17}
18
19impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> Reader<'a, T> {
20
21    pub(crate) fn new(buf: &'a mut Buffer<T>) -> Self {
22        Self {
23            buffer: buf,
24            bytes_read: Cell::new(0),
25            max_bytes: None
26        }
27    }
28
29    pub(crate) fn new_with_max(buf: &'a mut Buffer<T>, max_bytes: usize) -> Self {
30        Self {
31            buffer: buf,
32            bytes_read: Cell::new(0),
33            max_bytes: Some(max_bytes)
34        }
35    }
36
37    #[cfg(test)]
38    pub(crate) fn get_bytes_read(&self) -> usize {
39        self.bytes_read.get()
40    }
41}
42
43impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> BufferReader for Reader<'a, T> {
44    fn add_bytes_read(&self, n: usize) {
45        self.bytes_read.set(
46            self.bytes_read.get() + n
47        );
48    }
49}
50
51impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> Drop for Reader<'a, T> {
52    fn drop(&mut self) {
53        let bytes_read = self.bytes_read.get();
54        self.buffer.skip(bytes_read)
55            .expect("Reader: bytes_read must not be grater than the bytes skippable");
56    }
57}
58
59impl <'a, T: AsMut<[u8]> + AsRef<[u8]>> Deref for Reader<'a, T> {
60    type Target = [u8];
61
62    fn deref(&self) -> &Self::Target {
63        let src = self.buffer.data();
64        match self.max_bytes {
65            Some(max) => &src[..max],
66            None => src,
67        }
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use crate::{Buffer, BufferReader};
74    use super::Reader;
75
76
77    #[test]
78    fn test_read_skip() {
79        let mut b = [0u8; 8];
80        let mut buf = Buffer::new(&mut b);
81
82        let n = buf.write_base(&[1, 2, 3, 4]).unwrap();
83        assert_eq!(n, 4);
84
85        let reader = Reader::new(&mut buf);
86        assert_eq!(&reader[..], &[1, 2, 3, 4]);
87
88        reader.add_bytes_read(3);
89        assert_eq!(reader.get_bytes_read(), 3);
90        drop(reader);
91
92        assert_eq!(buf.read_position, 3);
93        assert_eq!(buf.write_position, 4);
94    }
95
96}