jbytes/
bytes.rs

1use core::{
2    ops::Deref,
3    cell::Cell,
4};
5use crate::BufRead;
6
7
8/// This is a Bytes<T> type for including byte stream data.
9/// 
10/// # Example
11/// 
12/// ```
13/// use jbytes::prelude::*;
14///
15///
16/// fn main() {
17///     let bytes = Bytes::new(b"\x01\x02\x03");
18///     assert_eq!(bytes.take_be_u16(), Ok(0x0102));
19///     assert_eq!(bytes.take_be_u16().is_err(), true);
20/// }
21/// ```
22#[derive(Debug)]
23pub struct Bytes<T> {
24    data: T,
25    position: Cell<usize>,
26}
27
28
29impl<T> Bytes<T> {
30    /// Constructs a new Bytes.
31    #[inline]
32    pub fn new(data: T) -> Self {
33        Self { data, position: Cell::new(0) }
34    }
35}
36
37
38impl<T> Deref for Bytes<T> {
39    type Target = T;
40
41    fn deref(&self) -> &Self::Target {
42        &self.data
43    }
44}
45
46
47impl<T> BufRead for Bytes<T>
48where
49    T: AsRef<[u8]>,
50{
51    #[inline]
52    fn get_position(&self) -> usize {
53        self.position.get()
54    }
55
56    #[inline]
57    fn get_data(&self) -> &'_ [u8] {
58        self.data.as_ref()
59    }
60
61    #[inline]
62    fn set_position(&self, position: usize) {
63        self.position.set(position);
64    }
65
66    #[inline]
67    fn reset_position(&self) {
68        self.position.set(0)
69    }
70
71    #[inline]
72    fn advance(&self, nbytes: usize) {
73        self.position.set(self.position.get() + nbytes)
74    }
75}
76
77
78pub trait ToBytes {
79    type Target: ?Sized;
80
81    /// Returns a Bytes<T> type.
82    fn to_bytes(&self) -> Bytes<&Self::Target>;
83}
84
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn test_bytes_take_u8() {
92        let buffer = Bytes::new(&[0x01, 0x02, 0x03]);
93        assert_eq!(buffer.take_u8().unwrap(), 0x01);
94        assert_eq!(buffer.take_u8().unwrap(), 0x02);
95        assert_eq!(buffer.remaining(), [0x03]);
96        assert_eq!(buffer.take_u8().unwrap(), 0x03);
97        assert_eq!(buffer.remaining_len(), 0);
98        assert_eq!(buffer.get_position(), 3);
99        assert_eq!(buffer.take_u8().is_err(), true);
100    }
101
102    #[test]
103    fn test_bytes_take() {
104        let buffer = Bytes::new([0x01, 0x02, 0x03, 0x04, 0x05]);
105        assert_eq!(buffer.take_bytes(2).unwrap(), &[0x01, 0x02]);
106        assert_eq!(buffer.take_bytes(2).unwrap(), &[0x03, 0x04]);
107        assert_eq!(buffer.remaining(), &[0x05]);
108        assert_eq!(buffer.take_bytes(2).is_err(), true);
109        assert_eq!(buffer.take_bytes(1).unwrap(), &[0x05]);
110        assert_eq!(buffer.get_position(), 5);
111    }
112
113    #[test]
114    fn test_bytes_untake() {
115        let buffer = Bytes::new([0x01, 0x02, 0x03, 0x04, 0x05]);
116        assert_eq!(buffer.remaining_len(), 5);
117        assert_eq!(buffer.untake_u32().unwrap(), 0x01020304);
118        assert_eq!(buffer.remaining_len(), 5);
119    }
120
121    #[test]
122    fn test_bytes_take_bytes_starts() {
123        let buffer = Bytes::new([0x01, 0x02, 0x03, 0x04, 0x05]);
124        assert_eq!(buffer.take_bytes_starts(b"\x01\x02\x04").is_err(), true);
125        assert_eq!(buffer.take_bytes_starts(b"\x01\x02\x03"), Ok(()));
126        assert_eq!(buffer.remaining_len(), 2);
127    }
128}