variable_len_reader/util/
write_buf.rs

1macro_rules! impl_write_buf {
2    () => {
3        #[inline]
4        pub fn len(&self) -> usize {
5            self.buf.as_ref().len()
6        }
7
8        #[inline]
9        pub fn buf(&self) -> &[u8] {
10            self.buf.as_ref()
11        }
12
13        #[inline]
14        pub fn position(&self) -> usize {
15            self.position
16        }
17
18        #[inline]
19        pub fn skip(&mut self, cnt: usize) {
20            let new = self.position.checked_add(cnt).expect("skip overflow");
21            assert!(
22                self.len() >= new,
23                "position ({}) must not become larger than buf.len ({})",
24                new, self.len()
25            );
26            self.position = new;
27        }
28
29        #[inline]
30        pub fn left(&self) -> usize {
31            self.len() - self.position
32        }
33
34        #[inline]
35        pub fn reset(&mut self) {
36            self.position = 0;
37        }
38
39        #[inline]
40        pub fn set_position(&mut self, position: usize) {
41            assert!(
42                self.len() >= position,
43                "position ({}) must not become larger than buf.len ({})",
44                position, self.len()
45            );
46            self.position = position;
47        }
48
49        #[inline]
50        pub fn get(&self) -> u8 {
51            self.buf.as_ref()[self.position]
52        }
53
54        #[inline]
55        pub fn take(&mut self) -> u8 {
56            assert!(
57                self.left() >= 1,
58                "no more readable bytes in buffer"
59            );
60            let val = self.get();
61            self.position += 1;
62            val
63        }
64
65        #[inline]
66        pub fn get_slice(&self, len: usize) -> &[u8] {
67            assert!(
68                self.left() >= len,
69                "not enough readable bytes in buffer"
70            );
71            &self.buf.as_ref()[self.position..self.position + len]
72        }
73
74        #[inline]
75        pub fn take_slice(&mut self, len: usize) -> &[u8] {
76            assert!(
77                self.left() >= len,
78                "not enough readable bytes in buffer"
79            );
80            let slice = &self.buf.as_ref()[self.position..self.position + len];
81            self.position += len;
82            slice
83        }
84    };
85}
86#[cfg(feature = "bytes")]
87macro_rules! impl_bytes_buf {
88    () => {
89        #[inline]
90        fn remaining(&self) -> usize {
91            self.left()
92        }
93
94        #[inline]
95        fn chunk(&self) -> &[u8] {
96            self.buf()
97        }
98
99        #[inline]
100        fn advance(&mut self, cnt: usize) {
101            self.skip(cnt)
102        }
103    };
104}
105
106#[derive(Debug)]
107pub struct WriteBuf<'a> {
108    buf: &'a [u8],
109    position: usize,
110}
111
112#[allow(dead_code)]
113impl<'a> WriteBuf<'a> {
114    pub fn new(buf: &'a [u8]) -> Self {
115        Self {
116            buf,
117            position: 0,
118        }
119    }
120
121    impl_write_buf!();
122}
123
124#[cfg(feature = "bytes")]
125#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
126impl<'a> bytes::Buf for WriteBuf<'a> {
127    impl_bytes_buf!();
128}
129
130
131/// The type parameter `B` should be `[u8, $n]`.
132#[derive(Debug)]
133pub struct OwnedWriteBuf<B: AsRef<[u8]>> {
134    buf: B,
135    position: usize
136}
137
138impl<B: AsRef<[u8]>> OwnedWriteBuf<B> {
139    pub fn new(buf: B) -> Self {
140        Self {
141            buf,
142            position: 0,
143        }
144    }
145
146    impl_write_buf!();
147}
148
149#[cfg(feature = "bytes")]
150#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
151impl<B: AsRef<[u8]>> bytes::Buf for OwnedWriteBuf<B> {
152    impl_bytes_buf!();
153}
154
155impl<'a, B: AsRef<[u8]>> From<&'a mut OwnedWriteBuf<B>> for WriteBuf<'a> {
156    #[inline]
157    fn from(value: &'a mut OwnedWriteBuf<B>) -> Self {
158        let mut buf = Self::new(value.buf.as_ref());
159        buf.set_position(value.position);
160        buf
161    }
162}
163
164
165#[cfg(test)]
166fn __owned_write_buf_u8_array() {
167    let _ = OwnedWriteBuf::<[u8; 16]>::new([0; 16]);
168}
169#[cfg(all(test, feature = "alloc"))]
170fn __owned_write_buf_u8_vec() {
171    let _ = OwnedWriteBuf::<alloc::vec::Vec<u8>>::new(alloc::vec::Vec::new());
172}