1#![cfg_attr(not(feature = "std"), no_std)]
23extern crate alloc;
24
25mod bbuf;
26mod slice;
27pub mod vec;
28mod zbuf;
29mod zslice;
30
31pub use bbuf::*;
32pub use zbuf::*;
33pub use zslice::*;
34
35#[cfg(any(test, feature = "test"))]
44#[macro_export]
45macro_rules! unsafe_slice {
46 ($s:expr,$r:expr) => {
47 &$s[$r]
48 };
49}
50
51#[cfg(any(test, feature = "test"))]
52#[macro_export]
53macro_rules! unsafe_slice_mut {
54 ($s:expr,$r:expr) => {
55 &mut $s[$r]
56 };
57}
58
59#[cfg(all(not(test), not(feature = "test")))]
60#[macro_export]
61macro_rules! unsafe_slice {
62 ($s:expr,$r:expr) => {{
63 let slice = &*$s;
64 let index = $r;
65 unsafe { slice.get_unchecked(index) }
66 }};
67}
68
69#[cfg(all(not(test), not(feature = "test")))]
70#[macro_export]
71macro_rules! unsafe_slice_mut {
72 ($s:expr,$r:expr) => {{
73 let slice = &mut *$s;
74 let index = $r;
75 unsafe { slice.get_unchecked_mut(index) }
76 }};
77}
78
79pub mod buffer {
80 use alloc::{borrow::Cow, vec::Vec};
81
82 pub trait Buffer {
83 fn len(&self) -> usize;
85
86 fn is_empty(&self) -> bool {
88 self.len() == 0
89 }
90 }
91
92 pub trait SplitBuffer: Buffer {
94 type Slices<'a>: Iterator<Item = &'a [u8]> + ExactSizeIterator
95 where
96 Self: 'a;
97
98 fn slices(&self) -> Self::Slices<'_>;
100
101 fn contiguous(&self) -> Cow<'_, [u8]> {
105 let mut slices = self.slices();
106 match slices.len() {
107 0 => Cow::Borrowed(b""),
108 1 => {
109 Cow::Borrowed(unsafe { slices.next().unwrap_unchecked() })
112 }
113 _ => Cow::Owned(slices.fold(Vec::with_capacity(self.len()), |mut acc, it| {
114 acc.extend_from_slice(it);
115 acc
116 })),
117 }
118 }
119 }
120}
121
122pub mod writer {
123 use core::num::NonZeroUsize;
124
125 use crate::ZSlice;
126
127 #[derive(Debug, Clone, Copy)]
128 pub struct DidntWrite;
129
130 pub trait Writer {
131 fn write(&mut self, bytes: &[u8]) -> Result<NonZeroUsize, DidntWrite>;
132 fn write_exact(&mut self, bytes: &[u8]) -> Result<(), DidntWrite>;
133 fn remaining(&self) -> usize;
134
135 fn write_u8(&mut self, byte: u8) -> Result<(), DidntWrite> {
136 self.write_exact(core::slice::from_ref(&byte))
137 }
138 fn write_zslice(&mut self, slice: &ZSlice) -> Result<(), DidntWrite> {
139 self.write_exact(slice.as_slice())
140 }
141 fn can_write(&self) -> bool {
142 self.remaining() != 0
143 }
144 unsafe fn with_slot<F>(&mut self, len: usize, write: F) -> Result<NonZeroUsize, DidntWrite>
152 where
153 F: FnOnce(&mut [u8]) -> usize;
154 }
155
156 impl<W: Writer + ?Sized> Writer for &mut W {
157 fn write(&mut self, bytes: &[u8]) -> Result<NonZeroUsize, DidntWrite> {
158 (**self).write(bytes)
159 }
160 fn write_exact(&mut self, bytes: &[u8]) -> Result<(), DidntWrite> {
161 (**self).write_exact(bytes)
162 }
163 fn remaining(&self) -> usize {
164 (**self).remaining()
165 }
166 fn write_u8(&mut self, byte: u8) -> Result<(), DidntWrite> {
167 (**self).write_u8(byte)
168 }
169 fn write_zslice(&mut self, slice: &ZSlice) -> Result<(), DidntWrite> {
170 (**self).write_zslice(slice)
171 }
172 fn can_write(&self) -> bool {
173 (**self).can_write()
174 }
175 unsafe fn with_slot<F>(&mut self, len: usize, write: F) -> Result<NonZeroUsize, DidntWrite>
176 where
177 F: FnOnce(&mut [u8]) -> usize,
178 {
179 unsafe { (**self).with_slot(len, write) }
181 }
182 }
183
184 pub trait BacktrackableWriter: Writer {
185 type Mark;
186
187 fn mark(&mut self) -> Self::Mark;
188 fn rewind(&mut self, mark: Self::Mark) -> bool;
189 }
190
191 impl<W: BacktrackableWriter + ?Sized> BacktrackableWriter for &mut W {
192 type Mark = W::Mark;
193 fn mark(&mut self) -> Self::Mark {
194 (**self).mark()
195 }
196 fn rewind(&mut self, mark: Self::Mark) -> bool {
197 (**self).rewind(mark)
198 }
199 }
200
201 pub trait HasWriter {
202 type Writer: Writer;
203
204 fn writer(self) -> Self::Writer;
206 }
207}
208
209pub mod reader {
210 use core::num::NonZeroUsize;
211
212 use crate::ZSlice;
213
214 #[derive(Debug, Clone, Copy)]
215 pub struct DidntRead;
216
217 pub trait Reader {
218 fn read(&mut self, into: &mut [u8]) -> Result<NonZeroUsize, DidntRead>;
219 fn read_exact(&mut self, into: &mut [u8]) -> Result<(), DidntRead>;
220 fn remaining(&self) -> usize;
221
222 fn read_zslices<F: FnMut(ZSlice)>(
224 &mut self,
225 len: usize,
226 for_each_slice: F,
227 ) -> Result<(), DidntRead>;
228
229 fn read_zslice(&mut self, len: usize) -> Result<ZSlice, DidntRead>;
231
232 fn read_u8(&mut self) -> Result<u8, DidntRead> {
233 let mut byte = 0;
234 let read = self.read(core::slice::from_mut(&mut byte))?;
235 if read.get() == 1 {
236 Ok(byte)
237 } else {
238 Err(DidntRead)
239 }
240 }
241
242 fn can_read(&self) -> bool {
243 self.remaining() != 0
244 }
245 }
246
247 impl<R: Reader + ?Sized> Reader for &mut R {
248 fn read(&mut self, into: &mut [u8]) -> Result<NonZeroUsize, DidntRead> {
249 (**self).read(into)
250 }
251 fn read_exact(&mut self, into: &mut [u8]) -> Result<(), DidntRead> {
252 (**self).read_exact(into)
253 }
254 fn remaining(&self) -> usize {
255 (**self).remaining()
256 }
257 fn read_zslices<F: FnMut(ZSlice)>(
258 &mut self,
259 len: usize,
260 for_each_slice: F,
261 ) -> Result<(), DidntRead> {
262 (**self).read_zslices(len, for_each_slice)
263 }
264 fn read_zslice(&mut self, len: usize) -> Result<ZSlice, DidntRead> {
265 (**self).read_zslice(len)
266 }
267 fn read_u8(&mut self) -> Result<u8, DidntRead> {
268 (**self).read_u8()
269 }
270 fn can_read(&self) -> bool {
271 (**self).can_read()
272 }
273 }
274
275 pub trait BacktrackableReader: Reader {
276 type Mark;
277
278 fn mark(&mut self) -> Self::Mark;
279 fn rewind(&mut self, mark: Self::Mark) -> bool;
280 }
281
282 impl<R: BacktrackableReader + ?Sized> BacktrackableReader for &mut R {
283 type Mark = R::Mark;
284 fn mark(&mut self) -> Self::Mark {
285 (**self).mark()
286 }
287 fn rewind(&mut self, mark: Self::Mark) -> bool {
288 (**self).rewind(mark)
289 }
290 }
291
292 pub trait AdvanceableReader: Reader {
293 fn skip(&mut self, offset: usize) -> Result<(), DidntRead>;
294 fn backtrack(&mut self, offset: usize) -> Result<(), DidntRead>;
295 fn advance(&mut self, offset: isize) -> Result<(), DidntRead> {
296 if offset > 0 {
297 self.skip(offset as usize)
298 } else {
299 self.backtrack((-offset) as usize)
300 }
301 }
302 }
303
304 #[derive(Debug, Clone, Copy)]
305 pub struct DidntSiphon;
306
307 pub trait SiphonableReader: Reader {
308 fn siphon<W>(&mut self, writer: &mut W) -> Result<NonZeroUsize, DidntSiphon>
309 where
310 W: crate::writer::Writer;
311 }
312
313 pub trait HasReader {
314 type Reader: Reader;
315
316 fn reader(self) -> Self::Reader;
318 }
319}