bufkit/
chunk.rs

1use crate::must_non_zero;
2
3use super::error::{
4  OutOfBounds, TryAdvanceError, TryPeekAtError, TryPeekError, TryReadError, TrySegmentError,
5};
6
7#[cfg(feature = "varint")]
8use core::num::NonZeroUsize;
9use core::ops::{Bound, RangeBounds};
10
11#[cfg(feature = "varint")]
12use varing::Varint;
13
14#[cfg(feature = "varint")]
15use super::error::{DecodeVarintAtError, DecodeVarintError};
16
17use super::panic_advance;
18
19pub use peeker::Peeker;
20pub use ref_peeker::RefPeeker;
21
22mod peeker;
23mod ref_peeker;
24
25macro_rules! peek_fixed {
26  ($($ty:ident), +$(,)?) => {
27    paste::paste! {
28      $(
29        #[doc = "Peeks a `" $ty "` value from the buffer in little-endian byte order without advancing the cursor."]
30        ///
31        /// Returns the decoded value. The buffer position remains unchanged after this operation.
32        ///
33        /// # Panics
34        ///
35        #[doc = "Panics if the buffer has fewer than `size_of::<" $ty ">()` bytes available."]
36        /// Use the `*_checked` or `try_*` variants for non-panicking peeks.
37        ///
38        /// # Examples
39        ///
40        /// ```rust
41        /// use bufkit::Chunk;
42        ///
43        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
44        /// let buf = &data[..];
45        #[doc = "assert_eq!(buf.peek_" $ty "_le(), <" $ty ">::from_le_bytes((&data[..size_of::<" $ty ">()]).try_into().unwrap()));"]
46        /// assert_eq!(buf.remaining(), data.len()); // Cursor unchanged
47        /// ```
48        #[inline]
49        fn [<peek_ $ty _le>](&self) -> $ty {
50          <$ty>::from_le_bytes(peek_array::<_, { core::mem::size_of::<$ty>() }>(self))
51        }
52
53        #[doc = "Peeks a `" $ty "` value from the buffer in little-endian byte order without advancing the cursor."]
54        ///
55        #[doc = "This is the non-panicking version of [`peek_" $ty "_le`](Chunk::peek_" $ty "_le)."]
56        /// Returns `Some(value)` if sufficient data is available, otherwise returns `None`.
57        ///
58        /// # Examples
59        ///
60        /// ```rust
61        /// use bufkit::Chunk;
62        ///
63        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
64        /// let buf = &data[..];
65        #[doc = "assert!(buf.peek_" $ty "_le_checked().is_some());"]
66        ///
67        /// let small_buf = &[0x34][..];
68        #[doc = "assert!(small_buf.peek_" $ty "_le_checked().is_none()); // Not enough bytes"]
69        /// ```
70        #[inline]
71        fn [<peek_ $ty _le_checked>](&self) -> Option<$ty> {
72          peek_array_checked::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_le_bytes)
73        }
74
75        #[doc = "Peeks a `" $ty "` value from the buffer in little-endian byte order without advancing the cursor."]
76        ///
77        #[doc = "This is the non-panicking version of [`peek_" $ty "_le`](Chunk::peek_" $ty "_le)."]
78        /// Returns `Ok(value)` on success, or `Err(TryPeekError)` with details about
79        /// requested vs available bytes.
80        ///
81        /// # Examples
82        ///
83        /// ```rust
84        /// use bufkit::Chunk;
85        ///
86        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
87        /// let buf = &data[..];
88        #[doc = "assert!(buf.try_peek_" $ty "_le().is_ok());"]
89        ///
90        /// let small_buf = &[0x34][..];
91        #[doc = "let err = small_buf.try_peek_" $ty "_le().unwrap_err();"]
92        /// // err contains details about requested vs available bytes
93        /// ```
94        #[inline]
95        fn [<try_peek_ $ty _le>](&self) -> Result<$ty, TryPeekError> {
96          try_peek_array::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_le_bytes)
97        }
98
99        #[doc = "Peeks a `" $ty "` value from the buffer in big-endian byte order without advancing the cursor."]
100        ///
101        /// Returns the decoded value. The buffer position remains unchanged after this operation.
102        ///
103        /// # Panics
104        ///
105        #[doc = "Panics if the buffer has fewer than `size_of::<" $ty ">()` bytes available."]
106        /// Use the `*_checked` or `try_*` variants for non-panicking peeks.
107        ///
108        /// # Examples
109        ///
110        /// ```rust
111        /// use bufkit::Chunk;
112        ///
113        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
114        /// let buf = &data[..];
115        #[doc = "assert_eq!(buf.peek_" $ty "_be(), <" $ty ">::from_be_bytes((&data[..size_of::<" $ty ">()]).try_into().unwrap()));"]
116        /// assert_eq!(buf.remaining(), data.len()); // Cursor unchanged
117        /// ```
118        #[inline]
119        fn [<peek_ $ty _be>](&self) -> $ty {
120          <$ty>::from_be_bytes(peek_array::<_, { core::mem::size_of::<$ty>() }>(self))
121        }
122
123        #[doc = "Peeks a `" $ty "` value from the buffer in big-endian byte order without advancing the cursor."]
124        ///
125        #[doc = "This is the non-panicking version of [`peek_" $ty "_be`](Chunk::peek_" $ty "_be)."]
126        /// Returns `Some(value)` if sufficient data is available, otherwise returns `None`.
127        ///
128        /// # Examples
129        ///
130        /// ```rust
131        /// use bufkit::Chunk;
132        ///
133        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
134        /// let buf = &data[..];
135        #[doc = "assert!(buf.peek_" $ty "_be_checked().is_some());"]
136        ///
137        /// let small_buf = &[0x12][..];
138        #[doc = "assert!(small_buf.peek_" $ty "_be_checked().is_none()); // Not enough bytes"]
139        /// ```
140        #[inline]
141        fn [<peek_ $ty _be_checked>](&self) -> Option<$ty> {
142          peek_array_checked::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_be_bytes)
143        }
144
145        #[doc = "Peeks a `" $ty "` value from the buffer in big-endian byte order without advancing the cursor."]
146        ///
147        #[doc = "This is the non-panicking version of [`peek_" $ty "_be`](Chunk::peek_" $ty "_be)."]
148        /// Returns `Ok(value)` on success, or `Err(TryPeekError)` with details about
149        /// requested vs available bytes.
150        ///
151        /// # Examples
152        ///
153        /// ```rust
154        /// use bufkit::Chunk;
155        ///
156        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
157        /// let buf = &data[..];
158        #[doc = "assert!(buf.try_peek_" $ty "_be().is_ok());"]
159        ///
160        /// let small_buf = &[0x12][..];
161        #[doc = "let err = small_buf.try_peek_" $ty "_be().unwrap_err();"]
162        /// // err contains details about requested vs available bytes
163        /// ```
164        #[inline]
165        fn [<try_peek_ $ty _be>](&self) -> Result<$ty, TryPeekError> {
166          try_peek_array::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_be_bytes)
167        }
168
169        #[doc = "Peeks a `" $ty "` value from the buffer in native-endian byte order without advancing the cursor."]
170        ///
171        /// The byte order depends on the target platform's endianness (little-endian on x86/x64,
172        /// big-endian on some embedded platforms).
173        ///
174        /// Returns the decoded value. The buffer position remains unchanged after this operation.
175        ///
176        /// # Panics
177        ///
178        #[doc = "Panics if the buffer has fewer than `size_of::<" $ty ">()` bytes available."]
179        /// Use the `*_checked` or `try_*` variants for non-panicking peeks.
180        ///
181        /// # Examples
182        ///
183        /// ```rust
184        /// use bufkit::Chunk;
185        ///
186        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
187        /// let buf = &data[..];
188        #[doc = "let value = buf.peek_" $ty "_ne();"]
189        /// assert_eq!(buf.remaining(), data.len()); // Cursor unchanged
190        /// ```
191        #[inline]
192        fn [<peek_ $ty _ne>](&self) -> $ty {
193          <$ty>::from_ne_bytes(peek_array::<_, { core::mem::size_of::<$ty>() }>(self))
194        }
195
196        #[doc = "Peeks a `" $ty "` value from the buffer in native-endian byte order without advancing the cursor."]
197        ///
198        /// The byte order depends on the target platform's endianness.
199        #[doc = "This is the non-panicking version of [`peek_" $ty "_ne`](Chunk::peek_" $ty "_ne)."]
200        /// Returns `Some(value)` if sufficient data is available, otherwise returns `None`.
201        ///
202        /// # Examples
203        ///
204        /// ```rust
205        /// use bufkit::Chunk;
206        ///
207        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
208        /// let buf = &data[..];
209        #[doc = "assert!(buf.peek_" $ty "_ne_checked().is_some());"]
210        ///
211        /// let small_buf = &[0x34][..];
212        #[doc = "assert!(small_buf.peek_" $ty "_ne_checked().is_none()); // Not enough bytes"]
213        /// ```
214        #[inline]
215        fn [<peek_ $ty _ne_checked>](&self) -> Option<$ty> {
216          peek_array_checked::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_ne_bytes)
217        }
218
219        #[doc = "Peeks a `" $ty "` value from the buffer in native-endian byte order without advancing the cursor."]
220        ///
221        /// The byte order depends on the target platform's endianness.
222        #[doc = "This is the non-panicking version of [`peek_" $ty "_ne`](Chunk::peek_" $ty "_ne)."]
223        /// Returns `Ok(value)` on success, or `Err(TryPeekError)` with details about
224        /// requested vs available bytes.
225        ///
226        /// # Examples
227        ///
228        /// ```rust
229        /// use bufkit::Chunk;
230        ///
231        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
232        /// let buf = &data[..];
233        #[doc = "assert!(buf.try_peek_" $ty "_ne().is_ok());"]
234        ///
235        /// let small_buf = &[0x34][..];
236        #[doc = "let err = small_buf.try_peek_" $ty "_ne().unwrap_err();"]
237        /// // err contains details about requested vs available bytes
238        /// ```
239        #[inline]
240        fn [<try_peek_ $ty _ne>](&self) -> Result<$ty, TryPeekError> {
241          try_peek_array::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_ne_bytes)
242        }
243
244        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in little-endian byte order."]
245        ///
246        /// Returns the decoded value without modifying the buffer position.
247        /// The offset is relative to the current buffer position.
248        ///
249        /// # Panics
250        ///
251        #[doc = "Panics if `offset + size_of::<" $ty ">() > self.remaining()`."]
252        /// Use the `*_checked` or `try_*` variants for non-panicking peeks.
253        ///
254        /// # Examples
255        ///
256        /// ```rust
257        /// use bufkit::Chunk;
258        ///
259        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
260        /// let buf = &data[..];
261        #[doc = "let value = buf.peek_" $ty "_le_at(2); // Peek at offset 2"]
262        /// assert_eq!(buf.remaining(), data.len()); // Chunkfer unchanged
263        /// ```
264        #[inline]
265        fn [<peek_ $ty _le_at>](&self, offset: usize) -> $ty {
266          <$ty>::from_le_bytes(peek_array_at::<_, { core::mem::size_of::<$ty>() }>(self, offset))
267        }
268
269        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in little-endian byte order."]
270        ///
271        #[doc = "This is the non-panicking version of [`peek_" $ty "_le_at`](Chunk::peek_" $ty "_le_at)."]
272        /// Returns `Some(value)` if sufficient data is available at the offset, otherwise returns `None`.
273        ///
274        /// # Examples
275        ///
276        /// ```rust
277        /// use bufkit::Chunk;
278        ///
279        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
280        /// let buf = &data[..];
281        #[doc = "assert!(buf.peek_" $ty "_le_at_checked(2).is_some());"]
282        #[doc = "assert!(buf.peek_" $ty "_le_at_checked(100).is_none()); // Out of bounds"]
283        /// ```
284        #[inline]
285        fn [<peek_ $ty _le_at_checked>](&self, offset: usize) -> Option<$ty> {
286          peek_array_at_checked::<_, { core::mem::size_of::<$ty>() }>(self, offset).map(<$ty>::from_le_bytes)
287        }
288
289        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in little-endian byte order."]
290        ///
291        #[doc = "This is the non-panicking version of [`peek_" $ty "_le_at`](Chunk::peek_" $ty "_le_at)."]
292        /// Returns `Ok(value)` on success, or `Err(TryPeekAtError)` with details about
293        /// the error condition (out of bounds or insufficient data).
294        ///
295        /// # Examples
296        ///
297        /// ```rust
298        /// use bufkit::Chunk;
299        ///
300        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
301        /// let buf = &data[..];
302        #[doc = "assert!(buf.try_peek_" $ty "_le_at(2).is_ok());"]
303        #[doc = "let err = buf.try_peek_" $ty "_le_at(100).unwrap_err();"]
304        /// // err contains details about the error
305        /// ```
306        #[inline]
307        fn [<try_peek_ $ty _le_at>](&self, offset: usize) -> Result<$ty, TryPeekAtError> {
308          try_peek_array_at::<_, { core::mem::size_of::<$ty>() }>(self, offset).map(<$ty>::from_le_bytes)
309        }
310
311        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in big-endian byte order."]
312        ///
313        /// Returns the decoded value without modifying the buffer position.
314        /// The offset is relative to the current buffer position.
315        ///
316        /// # Panics
317        ///
318        #[doc = "Panics if `offset + size_of::<" $ty ">() > self.remaining()`."]
319        /// Use the `*_checked` or `try_*` variants for non-panicking peeks.
320        ///
321        /// # Examples
322        ///
323        /// ```rust
324        /// use bufkit::Chunk;
325        ///
326        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
327        /// let buf = &data[..];
328        #[doc = "let value = buf.peek_" $ty "_be_at(2); // Peek at offset 2"]
329        /// assert_eq!(buf.remaining(), data.len()); // Chunkfer unchanged
330        /// ```
331        #[inline]
332        fn [<peek_ $ty _be_at>](&self, offset: usize) -> $ty {
333          <$ty>::from_be_bytes(peek_array_at::<_, { core::mem::size_of::<$ty>() }>(self, offset))
334        }
335
336        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in big-endian byte order."]
337        ///
338        #[doc = "This is the non-panicking version of [`peek_" $ty "_be_at`](Chunk::peek_" $ty "_be_at)."]
339        /// Returns `Some(value)` if sufficient data is available at the offset, otherwise returns `None`.
340        ///
341        /// # Examples
342        ///
343        /// ```rust
344        /// use bufkit::Chunk;
345        ///
346        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
347        /// let buf = &data[..];
348        #[doc = "assert!(buf.peek_" $ty "_be_at_checked(2).is_some());"]
349        #[doc = "assert!(buf.peek_" $ty "_be_at_checked(100).is_none()); // Out of bounds"]
350        /// ```
351        #[inline]
352        fn [<peek_ $ty _be_at_checked>](&self, offset: usize) -> Option<$ty> {
353          peek_array_at_checked::<_, { core::mem::size_of::<$ty>() }>(self, offset).map(<$ty>::from_be_bytes)
354        }
355
356        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in big-endian byte order."]
357        ///
358        #[doc = "This is the non-panicking version of [`peek_" $ty "_be_at`](Chunk::peek_" $ty "_be_at)."]
359        /// Returns `Ok(value)` on success, or `Err(TryPeekAtError)` with details about
360        /// the error condition (out of bounds or insufficient data).
361        ///
362        /// # Examples
363        ///
364        /// ```rust
365        /// use bufkit::Chunk;
366        ///
367        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
368        /// let buf = &data[..];
369        #[doc = "assert!(buf.try_peek_" $ty "_be_at(2).is_ok());"]
370        #[doc = "let err = buf.try_peek_" $ty "_be_at(100).unwrap_err();"]
371        /// // err contains details about the error
372        /// ```
373        #[inline]
374        fn [<try_peek_ $ty _be_at>](&self, offset: usize) -> Result<$ty, TryPeekAtError> {
375          try_peek_array_at::<_, { core::mem::size_of::<$ty>() }>(self, offset).map(<$ty>::from_be_bytes)
376        }
377
378        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in native-endian byte order."]
379        ///
380        /// The byte order depends on the target platform's endianness.
381        /// Returns the decoded value without modifying the buffer position.
382        /// The offset is relative to the current buffer position.
383        ///
384        /// # Panics
385        ///
386        #[doc = "Panics if `offset + size_of::<" $ty ">() > self.remaining()`."]
387        /// Use the `*_checked` or `try_*` variants for non-panicking peeks.
388        ///
389        /// # Examples
390        ///
391        /// ```rust
392        /// use bufkit::Chunk;
393        ///
394        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
395        /// let buf = &data[..];
396        #[doc = "let value = buf.peek_" $ty "_ne_at(2); // Peek at offset 2"]
397        /// assert_eq!(buf.remaining(), data.len()); // Chunkfer unchanged
398        /// ```
399        #[inline]
400        fn [<peek_ $ty _ne_at>](&self, offset: usize) -> $ty {
401          <$ty>::from_ne_bytes(peek_array_at::<_, { core::mem::size_of::<$ty>() }>(self, offset))
402        }
403
404        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in native-endian byte order."]
405        ///
406        /// The byte order depends on the target platform's endianness.
407        #[doc = "This is the non-panicking version of [`peek_" $ty "_ne_at`](Chunk::peek_" $ty "_ne_at)."]
408        /// Returns `Some(value)` if sufficient data is available at the offset, otherwise returns `None`.
409        ///
410        /// # Examples
411        ///
412        /// ```rust
413        /// use bufkit::Chunk;
414        ///
415        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
416        /// let buf = &data[..];
417        #[doc = "assert!(buf.peek_" $ty "_ne_at_checked(2).is_some());"]
418        #[doc = "assert!(buf.peek_" $ty "_ne_at_checked(100).is_none()); // Out of bounds"]
419        /// ```
420        #[inline]
421        fn [<peek_ $ty _ne_at_checked>](&self, offset: usize) -> Option<$ty> {
422          peek_array_at_checked::<_, { core::mem::size_of::<$ty>() }>(self, offset).map(<$ty>::from_ne_bytes)
423        }
424
425        #[doc = "Peeks a `" $ty "` value from the buffer at the specified offset in native-endian byte order."]
426        ///
427        /// The byte order depends on the target platform's endianness.
428        #[doc = "This is the non-panicking version of [`peek_" $ty "_ne_at`](Chunk::peek_" $ty "_ne_at)."]
429        /// Returns `Ok(value)` on success, or `Err(TryPeekAtError)` with details about
430        /// the error condition (out of bounds or insufficient data).
431        ///
432        /// # Examples
433        ///
434        /// ```rust
435        /// use bufkit::Chunk;
436        ///
437        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
438        /// let buf = &data[..];
439        #[doc = "assert!(buf.try_peek_" $ty "_ne_at(0).is_ok());"]
440        #[doc = "let err = buf.try_peek_" $ty "_ne_at(100).unwrap_err();"]
441        /// // err contains details about the error
442        /// ```
443        #[inline]
444        fn [<try_peek_ $ty _ne_at>](&self, offset: usize) -> Result<$ty, TryPeekAtError> {
445          try_peek_array_at::<_, { core::mem::size_of::<$ty>() }>(self, offset).map(<$ty>::from_ne_bytes)
446        }
447      )*
448    }
449  };
450  (@forward $($ty:ident), +$(,)?) => {
451    paste::paste! {
452      $(
453        #[inline]
454        fn [<peek_ $ty _le>](&self) -> $ty {
455          (**self).[<peek_ $ty _le>]()
456        }
457
458        #[inline]
459        fn [<peek_ $ty _le_checked>](&self) -> Option<$ty> {
460          (**self).[<peek_ $ty _le_checked>]()
461        }
462
463        #[inline]
464        fn [<try_peek_ $ty _le>](&self) -> Result<$ty, TryPeekError> {
465          (**self).[<try_peek_ $ty _le>]()
466        }
467
468        #[inline]
469        fn [<peek_ $ty _be>](&self) -> $ty {
470          (**self).[<peek_ $ty _be>]()
471        }
472
473        #[inline]
474        fn [<peek_ $ty _be_checked>](&self) -> Option<$ty> {
475          (**self).[<peek_ $ty _be_checked>]()
476        }
477
478        #[inline]
479        fn [<try_peek_ $ty _be>](&self) -> Result<$ty, TryPeekError> {
480          (**self).[<try_peek_ $ty _be>]()
481        }
482
483        #[inline]
484        fn [<peek_ $ty _ne>](&self) -> $ty {
485          (**self).[<peek_ $ty _ne>]()
486        }
487
488        #[inline]
489        fn [<peek_ $ty _ne_checked>](&self) -> Option<$ty> {
490          (**self).[<peek_ $ty _ne_checked>]()
491        }
492
493        #[inline]
494        fn [<try_peek_ $ty _ne>](&self) -> Result<$ty, TryPeekError> {
495          (**self).[<try_peek_ $ty _ne>]()
496        }
497
498        #[inline]
499        fn [<peek_ $ty _le_at>](&self, offset: usize) -> $ty {
500          (**self).[<peek_ $ty _le_at>](offset)
501        }
502
503        #[inline]
504        fn [<peek_ $ty _le_at_checked>](&self, offset: usize) -> Option<$ty> {
505          (**self).[<peek_ $ty _le_at_checked>](offset)
506        }
507
508        #[inline]
509        fn [<try_peek_ $ty _le_at>](&self, offset: usize) -> Result<$ty, TryPeekAtError> {
510          (**self).[<try_peek_ $ty _le_at>](offset)
511        }
512
513        #[inline]
514        fn [<peek_ $ty _be_at>](&self, offset: usize) -> $ty {
515          (**self).[<peek_ $ty _be_at>](offset)
516        }
517
518        #[inline]
519        fn [<peek_ $ty _be_at_checked>](&self, offset: usize) -> Option<$ty> {
520          (**self).[<peek_ $ty _be_at_checked>](offset)
521        }
522
523        #[inline]
524        fn [<try_peek_ $ty _be_at>](&self, offset: usize) -> Result<$ty, TryPeekAtError> {
525          (**self).[<try_peek_ $ty _be_at>](offset)
526        }
527
528        #[inline]
529        fn [<peek_ $ty _ne_at>](&self, offset: usize) -> $ty {
530          (**self).[<peek_ $ty _ne_at>](offset)
531        }
532
533        #[inline]
534        fn [<peek_ $ty _ne_at_checked>](&self, offset: usize) -> Option<$ty> {
535          (**self).[<peek_ $ty _ne_at_checked>](offset)
536        }
537
538        #[inline]
539        fn [<try_peek_ $ty _ne_at>](&self, offset: usize) -> Result<$ty, TryPeekAtError> {
540          (**self).[<try_peek_ $ty _ne_at>](offset)
541        }
542      )*
543    }
544  };
545}
546
547macro_rules! read_fixed {
548  ($($ty:ident), +$(,)?) => {
549    paste::paste! {
550      $(
551        #[doc = "Reads a `" $ty "` value from the buffer in little-endian byte order and advances the cursor."]
552        ///
553        #[doc = "Returns the decoded value and advances the cursor by `size_of::<" $ty ">()` bytes."]
554        ///
555        /// # Panics
556        ///
557        #[doc = "Panics if the buffer has fewer than `size_of::<" $ty ">()` bytes available."]
558        /// Use the `*_checked` or `try_*` variants for non-panicking reads.
559        ///
560        /// # Examples
561        ///
562        /// ```rust
563        /// use bufkit::Chunk;
564        ///
565        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
566        /// let mut buf = &data[..];
567        #[doc = "let value = buf.read_" $ty "_le();"]
568        #[doc = "assert_eq!(buf.remaining(), data.len() - size_of::<" $ty ">()); // Cursor advanced"]
569        /// ```
570        #[inline]
571        fn [<read_ $ty _le>](&mut self) -> $ty {
572          <$ty>::from_le_bytes(read_array::<_, { core::mem::size_of::<$ty>() }>(self))
573        }
574
575        #[doc = "Reads a `" $ty "` value from the buffer in little-endian byte order and advances the cursor."]
576        ///
577        #[doc = "This is the non-panicking version of [`read_" $ty "_le`](Chunk::read_" $ty "_le)."]
578        /// Returns `Some(value)` and advances the cursor on success, or `None` if insufficient data.
579        ///
580        /// # Examples
581        ///
582        /// ```rust
583        /// use bufkit::Chunk;
584        ///
585        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
586        /// let mut buf = &data[..];
587        #[doc = "if let Some(value) = buf.read_" $ty "_le_checked() {"]
588        #[doc = "    // Cursor advanced by size_of::<" $ty ">()"]
589        /// } else {
590        ///     // Not enough data, cursor unchanged
591        /// }
592        /// ```
593        #[inline]
594        fn [<read_ $ty _le_checked>](&mut self) -> Option<$ty> {
595          read_array_checked::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_le_bytes)
596        }
597
598        #[doc = "Reads a `" $ty "` value from the buffer in little-endian byte order and advances the cursor."]
599        ///
600        #[doc = "This is the non-panicking version of [`read_" $ty "_le`](Chunk::read_" $ty "_le)."]
601        /// Returns `Ok(value)` and advances the cursor on success, or `Err(TryReadError)`
602        /// with details about requested vs available bytes.
603        ///
604        /// # Examples
605        ///
606        /// ```rust
607        /// use bufkit::Chunk;
608        ///
609        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
610        /// let mut buf = &data[..];
611        #[doc = "match buf.try_read_" $ty "_le() {"]
612        ///     Ok(value) => {
613        #[doc = "        // Cursor advanced by size_of::<" $ty ">()"]
614        ///     },
615        ///     Err(e) => {
616        ///         // e contains details about requested vs available bytes
617        ///     }
618        /// }
619        /// ```
620        #[inline]
621        fn [<try_read_ $ty _le>](&mut self) -> Result<$ty, TryReadError> {
622          try_read_array::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_le_bytes)
623        }
624
625        #[doc = "Reads a `" $ty "` value from the buffer in big-endian byte order and advances the cursor."]
626        ///
627        #[doc = "Returns the decoded value and advances the cursor by `size_of::<" $ty ">()` bytes."]
628        ///
629        /// # Panics
630        ///
631        #[doc = "Panics if the buffer has fewer than `size_of::<" $ty ">()` bytes available."]
632        /// Use the `*_checked` or `try_*` variants for non-panicking reads.
633        ///
634        /// # Examples
635        ///
636        /// ```rust
637        /// use bufkit::Chunk;
638        ///
639        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
640        /// let mut buf = &data[..];
641        #[doc = "let value = buf.read_" $ty "_be();"]
642        #[doc = "assert_eq!(buf.remaining(), data.len() - size_of::<" $ty ">()); // Cursor advanced"]
643        /// ```
644        #[inline]
645        fn [<read_ $ty _be>](&mut self) -> $ty {
646          <$ty>::from_be_bytes(read_array::<_, { core::mem::size_of::<$ty>() }>(self))
647        }
648
649        #[doc = "Reads a `" $ty "` value from the buffer in big-endian byte order and advances the cursor."]
650        ///
651        #[doc = "This is the non-panicking version of [`read_" $ty "_be`](Chunk::read_" $ty "_be)."]
652        /// Returns `Some(value)` and advances the cursor on success, or `None` if insufficient data.
653        ///
654        /// # Examples
655        ///
656        /// ```rust
657        /// use bufkit::Chunk;
658        ///
659        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
660        /// let mut buf = &data[..];
661        #[doc = "if let Some(value) = buf.read_" $ty "_be_checked() {"]
662        #[doc = "    // Cursor advanced by size_of::<" $ty ">()"]
663        /// } else {
664        ///     // Not enough data, cursor unchanged
665        /// }
666        /// ```
667        #[inline]
668        fn [<read_ $ty _be_checked>](&mut self) -> Option<$ty> {
669          read_array_checked::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_be_bytes)
670        }
671
672        #[doc = "Reads a `" $ty "` value from the buffer in big-endian byte order and advances the cursor."]
673        ///
674        #[doc = "This is the non-panicking version of [`read_" $ty "_be`](Chunk::read_" $ty "_be)."]
675        /// Returns `Ok(value)` and advances the cursor on success, or `Err(TryReadError)`
676        /// with details about requested vs available bytes.
677        ///
678        /// # Examples
679        ///
680        /// ```rust
681        /// use bufkit::Chunk;
682        ///
683        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
684        /// let mut buf = &data[..];
685        #[doc = "match buf.try_read_" $ty "_be() {"]
686        ///     Ok(value) => {
687        #[doc = "        // Cursor advanced by size_of::<" $ty ">()"]
688        ///     },
689        ///     Err(e) => {
690        ///         // e contains details about requested vs available bytes
691        ///     }
692        /// }
693        /// ```
694        #[inline]
695        fn [<try_read_ $ty _be>](&mut self) -> Result<$ty, TryReadError> {
696          try_read_array::<_, { core::mem::size_of::<$ty>() }>(self).map(|val| { <$ty>::from_be_bytes(val) })
697        }
698
699        #[doc = "Reads a `" $ty "` value from the buffer in native-endian byte order and advances the cursor."]
700        ///
701        /// The byte order depends on the target platform's endianness (little-endian on x86/x64,
702        /// big-endian on some embedded platforms).
703        ///
704        #[doc = "Returns the decoded value and advances the cursor by `size_of::<" $ty ">()` bytes."]
705        ///
706        /// # Panics
707        ///
708        #[doc = "Panics if the buffer has fewer than `size_of::<" $ty ">()` bytes available."]
709        /// Use the `*_checked` or `try_*` variants for non-panicking reads.
710        ///
711        /// # Examples
712        ///
713        /// ```rust
714        /// use bufkit::Chunk;
715        ///
716        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
717        /// let mut buf = &data[..];
718        #[doc = "let value = buf.read_" $ty "_ne();"]
719        #[doc = "assert_eq!(buf.remaining(), data.len() - size_of::<" $ty ">()); // Cursor advanced"]
720        /// ```
721        #[inline]
722        fn [<read_ $ty _ne>](&mut self) -> $ty {
723          <$ty>::from_ne_bytes(read_array::<_, { core::mem::size_of::<$ty>() }>(self))
724        }
725
726        #[doc = "Reads a `" $ty "` value from the buffer in native-endian byte order and advances the cursor."]
727        ///
728        /// The byte order depends on the target platform's endianness.
729        #[doc = "This is the non-panicking version of [`read_" $ty "_ne`](Chunk::read_" $ty "_ne)."]
730        /// Returns `Some(value)` and advances the cursor on success, or `None` if insufficient data.
731        ///
732        /// # Examples
733        ///
734        /// ```rust
735        /// use bufkit::Chunk;
736        ///
737        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
738        /// let mut buf = &data[..];
739        #[doc = "if let Some(value) = buf.read_" $ty "_ne_checked() {"]
740        #[doc = "    // Cursor advanced by size_of::<" $ty ">()"]
741        /// } else {
742        ///     // Not enough data, cursor unchanged
743        /// }
744        /// ```
745        #[inline]
746        fn [<read_ $ty _ne_checked>](&mut self) -> Option<$ty> {
747          read_array_checked::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_ne_bytes)
748        }
749
750        #[doc = "Reads a `" $ty "` value from the buffer in native-endian byte order and advances the cursor."]
751        ///
752        /// The byte order depends on the target platform's endianness.
753        #[doc = "This is the non-panicking version of [`read_" $ty "_ne`](Chunk::read_" $ty "_ne)."]
754        /// Returns `Ok(value)` and advances the cursor on success, or `Err(TryReadError)`
755        /// with details about requested vs available bytes.
756        ///
757        /// # Examples
758        ///
759        /// ```rust
760        /// use bufkit::Chunk;
761        ///
762        /// let data = [147, 23, 89, 201, 156, 74, 33, 198, 67, 142, 91, 205, 38, 177, 124, 59, 183, 96, 241, 167, 82, 135, 49, 213];
763        /// let mut buf = &data[..];
764        #[doc = "match buf.try_read_" $ty "_ne() {"]
765        ///     Ok(value) => {
766        #[doc = "        // Cursor advanced by size_of::<" $ty ">()"]
767        ///     },
768        ///     Err(e) => {
769        ///         // e contains details about requested vs available bytes
770        ///     }
771        /// }
772        /// ```
773        #[inline]
774        fn [<try_read_ $ty _ne>](&mut self) -> Result<$ty, TryReadError> {
775          try_read_array::<_, { core::mem::size_of::<$ty>() }>(self).map(<$ty>::from_ne_bytes)
776        }
777      )*
778    }
779  };
780  (@forward $($ty:ident), +$(,)?) => {
781    paste::paste! {
782      $(
783        #[inline]
784        fn [<read_ $ty _le>](&mut self) -> $ty {
785          (**self).[<read_ $ty _le>]()
786        }
787
788        #[inline]
789        fn [<read_ $ty _le_checked>](&mut self) -> Option<$ty> {
790          (**self).[<read_ $ty _le_checked>]()
791        }
792
793        #[inline]
794        fn [<try_read_ $ty _le>](&mut self) -> Result<$ty, TryReadError> {
795          (**self).[<try_read_ $ty _le>]()
796        }
797
798        #[inline]
799        fn [<read_ $ty _be>](&mut self) -> $ty {
800          (**self).[<read_ $ty _be>]()
801        }
802
803        #[inline]
804        fn [<read_ $ty _be_checked>](&mut self) -> Option<$ty> {
805          (**self).[<read_ $ty _be_checked>]()
806        }
807
808        #[inline]
809        fn [<try_read_ $ty _be>](&mut self) -> Result<$ty, TryReadError> {
810          (**self).[<try_read_ $ty _be>]()
811        }
812
813        #[inline]
814        fn [<read_ $ty _ne>](&mut self) -> $ty {
815          (**self).[<read_ $ty _ne>]()
816        }
817
818        #[inline]
819        fn [<read_ $ty _ne_checked>](&mut self) -> Option<$ty> {
820          (**self).[<read_ $ty _ne_checked>]()
821        }
822
823        #[inline]
824        fn [<try_read_ $ty _ne>](&mut self) -> Result<$ty, TryReadError> {
825          (**self).[<try_read_ $ty _ne>]()
826        }
827      )*
828    }
829  };
830}
831
832/// A trait for implementing custom buffers that can read and navigate through byte sequences.
833///
834/// This trait provides a comprehensive set of methods for reading data from buffers with different
835/// error handling strategies:
836/// - **Panicking methods** (e.g., `read_*`): Fast operations that panic on insufficient data
837/// - **Checked methods** (e.g., `*_checked`): Return `Option` - `None` on failure, `Some(value)` on success
838/// - **Fallible methods** (e.g., `try_*`): Return `Result` with detailed error information
839///
840/// # Method Categories
841///
842/// - **Chunkfer inspection**: `remaining()`, `has_remaining()`, `buffer()`
843/// - **Navigation**: `advance()`, `try_advance()`
844/// - **Chunkfer manipulation**: `truncate()`, `split_to()`, `split_off()`, `segment()`
845/// - **Peeking data**: `peek_u8()`, `peek_u16_le()`, etc. (read without advancing)
846/// - **Reading data**: `read_u8()`, `read_u16_le()`, etc. (read and advance cursor)
847pub trait Chunk {
848  /// Returns the number of bytes available for reading in the buffer.
849  ///
850  /// This represents how many bytes can be read from the current cursor position
851  /// to the end of the buffer.
852  ///
853  /// # Examples
854  ///
855  /// ```rust
856  /// use bufkit::Chunk;
857  ///
858  /// let data = [1, 2, 3, 4, 5];
859  /// let mut buf = &data[..];
860  /// assert_eq!(buf.remaining(), 5);
861  ///
862  /// buf.advance(2);
863  /// assert_eq!(buf.remaining(), 3);
864  /// ```
865  fn remaining(&self) -> usize;
866
867  /// Returns the remaining bytes of the buffer as a slice.
868  ///
869  /// This provides direct access to all bytes from the current cursor position
870  /// to the end of the buffer.
871  ///
872  /// # Examples
873  ///
874  /// ```rust
875  /// use bufkit::Chunk;
876  ///
877  /// let data = [1, 2, 3, 4, 5];
878  /// let mut buf = &data[..];
879  /// assert_eq!(buf.buffer(), &[1, 2, 3, 4, 5]);
880  ///
881  /// buf.advance(2);
882  /// assert_eq!(buf.buffer(), &[3, 4, 5]);
883  /// ```
884  fn buffer(&self) -> &[u8];
885
886  /// Returns a slice of the buffer starting from the specified offset.
887  ///
888  /// This is similar to [`buffer`](Chunk::buffer) but starts from the given offset
889  /// rather than the current cursor position.
890  ///
891  /// # Panics
892  ///
893  /// Panics if `offset > self.remaining()`.
894  /// Use [`buffer_from_checked`](Chunk::buffer_from_checked) for non-panicking access.
895  ///
896  /// # Examples
897  ///
898  /// ```rust
899  /// use bufkit::Chunk;
900  ///
901  /// let data = [1u8, 2, 3, 4, 5];
902  /// let buf = &data[..];
903  ///
904  /// assert_eq!(buf.buffer(), &[1, 2, 3, 4, 5]);
905  /// assert_eq!(buf.buffer_from(2), &[3, 4, 5]);
906  /// ```
907  #[inline]
908  fn buffer_from(&self, offset: usize) -> &[u8] {
909    &self.buffer()[offset..]
910  }
911
912  /// Returns a slice of the buffer starting from the specified offset.
913  ///
914  /// This is the non-panicking version of [`buffer_from`](Chunk::buffer_from).
915  /// Returns `Some(slice)` if `offset <= self.remaining()`, otherwise returns `None`.
916  ///
917  /// # Examples
918  ///
919  /// ```rust
920  /// use bufkit::Chunk;
921  ///
922  /// let data = [1u8, 2, 3, 4, 5];
923  /// let buf = &data[..];
924  ///
925  /// assert_eq!(buf.buffer_from_checked(2), Some(&[3, 4, 5][..]));
926  /// assert!(buf.buffer_from_checked(5).unwrap().is_empty()); // empty buffer
927  /// assert_eq!(buf.buffer_from_checked(10), None); // Out of bounds
928  /// ```
929  #[inline]
930  fn buffer_from_checked(&self, offset: usize) -> Option<&[u8]> {
931    if offset > self.remaining() {
932      None
933    } else {
934      Some(&self.buffer()[offset..])
935    }
936  }
937
938  /// Advances the internal cursor by the specified number of bytes.
939  ///
940  /// This moves the read position forward, making the advanced bytes no longer
941  /// available for reading. The operation consumes the bytes without returning them.
942  ///
943  /// # Panics
944  ///
945  /// Panics if `cnt > self.remaining()`.
946  /// Use [`try_advance`](Chunk::try_advance) for non-panicking advancement.
947  ///
948  /// # Examples
949  ///
950  /// ```rust
951  /// use bufkit::Chunk;
952  ///
953  /// let data = [1, 2, 3, 4, 5];
954  /// let mut buf = &data[..];
955  ///
956  /// buf.advance(2);
957  /// assert_eq!(buf.remaining(), 3);
958  /// assert_eq!(buf.buffer(), &[3, 4, 5]);
959  /// ```
960  fn advance(&mut self, cnt: usize);
961
962  /// Returns a slice containing the first `len` bytes of the buffer.
963  ///
964  /// This provides access to a prefix of the buffer for efficient manipulation
965  /// of a specific portion without affecting the rest of the buffer.
966  ///
967  /// # Panics
968  ///
969  /// Panics if `len > self.remaining()`.
970  /// Use [`prefix_checked`](Chunk::prefix_checked) for non-panicking access.
971  ///
972  /// # Examples
973  ///
974  /// ```rust
975  /// use bufkit::Chunk;
976  ///
977  /// let mut buf = [1u8, 2, 3, 4, 5];
978  /// let slice = &buf[..];
979  /// let prefix = Chunk::prefix(&slice, 3);
980  /// assert_eq!(prefix, [1u8, 2, 3].as_slice());
981  /// ```
982  #[inline]
983  fn prefix(&self, len: usize) -> &[u8] {
984    &self.buffer()[..len]
985  }
986
987  /// Returns a slice containing the first `len` bytes of the buffer.
988  ///
989  /// This is the non-panicking version of [`prefix`](Chunk::prefix).
990  /// Returns `Some(slice)` if `len <= self.remaining()`, otherwise returns `None`.
991  ///
992  /// # Examples
993  ///
994  /// ```rust
995  /// use bufkit::Chunk;
996  ///
997  /// let mut buf = [1u8, 2, 3, 4, 5];
998  ///
999  /// assert_eq!(Chunk::prefix_checked(&&buf[..], 3).unwrap(), &[1, 2, 3]);
1000  /// assert_eq!(Chunk::prefix_checked(&&buf[..], 5).unwrap(), &[1, 2, 3, 4, 5]);
1001  /// assert!(Chunk::prefix_checked(&&buf[..], 10).is_none());
1002  /// ```
1003  #[inline]
1004  fn prefix_checked(&self, len: usize) -> Option<&[u8]> {
1005    if self.remaining() < len {
1006      None
1007    } else {
1008      Some(&self.buffer()[..len])
1009    }
1010  }
1011
1012  /// Returns a slice containing the last `len` bytes of the buffer.
1013  ///
1014  /// This provides access to a suffix of the buffer for efficient manipulation
1015  /// of the trailing portion without affecting the rest of the buffer.
1016  ///
1017  /// # Panics
1018  ///
1019  /// Panics if `len > self.remaining()`.
1020  /// Use [`suffix_checked`](Chunk::suffix_checked) for non-panicking access.
1021  ///
1022  /// # Examples
1023  ///
1024  /// ```rust
1025  /// use bufkit::Chunk;
1026  ///
1027  /// let mut buf = [1u8, 2, 3, 4, 5];
1028  ///
1029  /// let slice = &buf[..];
1030  /// let suffix = Chunk::suffix(&slice, 2);
1031  /// assert_eq!(suffix, &[4, 5]);
1032  /// ```
1033  #[inline]
1034  fn suffix(&self, len: usize) -> &[u8] {
1035    let total_len = self.remaining();
1036    &self.buffer()[total_len - len..]
1037  }
1038
1039  /// Returns a slice containing the last `len` bytes of the buffer.
1040  ///
1041  /// This is the non-panicking version of [`suffix`](Chunk::suffix).
1042  /// Returns `Some(slice)` if `len <= self.remaining()`, otherwise returns `None`.
1043  ///
1044  /// # Examples
1045  ///
1046  /// ```rust
1047  /// use bufkit::Chunk;
1048  ///
1049  /// let mut buf = [1u8, 2, 3, 4, 5];
1050  /// let slice = &buf[..];
1051  /// assert_eq!(Chunk::suffix_checked(&slice, 2).unwrap(), &[4, 5]);
1052  /// assert_eq!(Chunk::suffix_checked(&slice, 5).unwrap(), &[1, 2, 3, 4, 5]);
1053  /// assert!(Chunk::suffix_checked(&slice, 10).is_none());
1054  /// ```
1055  #[inline]
1056  fn suffix_checked(&self, len: usize) -> Option<&[u8]> {
1057    self
1058      .remaining()
1059      .checked_sub(len)
1060      .map(|start| &self.buffer()[start..])
1061  }
1062
1063  /// Creates an independent buffer containing a segment of the current buffer's data.
1064  ///
1065  /// This method returns a new buffer instance that represents a portion of the current
1066  /// buffer defined by the given range. The original buffer remains unchanged,
1067  /// and the new buffer has its own independent cursor starting at the beginning of the segment.
1068  ///
1069  /// # Panics
1070  ///
1071  /// Panics if the range is out of bounds relative to the current buffer's available data.
1072  /// Use [`try_segment`](Chunk::try_segment) for non-panicking segmentation.
1073  ///
1074  /// # Examples
1075  ///
1076  /// ```rust
1077  /// use bufkit::Chunk;
1078  ///
1079  /// let data = b"Hello, World!";
1080  /// let buf = &data[..];
1081  ///
1082  /// let hello = buf.segment(0..5);
1083  /// let world = buf.segment(7..12);
1084  ///
1085  /// assert_eq!(hello.buffer(), b"Hello");
1086  /// assert_eq!(world.buffer(), b"World");
1087  /// // Original buffer unchanged
1088  /// assert_eq!(buf.remaining(), 13);
1089  /// ```
1090  fn segment(&self, range: impl RangeBounds<usize>) -> Self
1091  where
1092    Self: Sized;
1093
1094  /// Shortens the buffer to the specified length, keeping the first `len` bytes.
1095  ///
1096  /// If `len` is greater than the buffer's current available bytes, this has no effect.
1097  /// This operation cannot fail and will never panic.
1098  ///
1099  /// # Examples
1100  ///
1101  /// ```rust
1102  /// use bufkit::Chunk;
1103  ///
1104  /// let data = [1, 2, 3, 4, 5];
1105  /// let mut buf = &data[..];
1106  ///
1107  /// buf.truncate(3);
1108  /// assert_eq!(buf.remaining(), 3);
1109  /// assert_eq!(buf.buffer(), &[1, 2, 3]);
1110  ///
1111  /// // Truncating to a length >= available has no effect
1112  /// buf.truncate(10);
1113  /// assert_eq!(buf.remaining(), 3);
1114  /// ```
1115  fn truncate(&mut self, len: usize);
1116
1117  /// Splits the buffer into two at the given index.
1118  ///
1119  /// Afterwards `self` contains elements `[0, at)`, and the returned buffer
1120  /// contains elements `[at, remaining())`. The memory layout remains unchanged.
1121  ///
1122  /// **Implementor Notes:** This should be an `O(1)` operation.
1123  ///
1124  /// # Panics
1125  ///
1126  /// Panics if `at > self.remaining()`.
1127  /// Use [`split_off_checked`](Chunk::split_off_checked) or
1128  /// [`try_split_off`](Chunk::try_split_off) for non-panicking splits.
1129  ///
1130  /// # Examples
1131  ///
1132  /// ```rust
1133  /// use bufkit::Chunk;
1134  ///
1135  /// let data = [1, 2, 3, 4, 5];
1136  /// let mut buf = &data[..];
1137  ///
1138  /// let tail = Chunk::split_off(&mut buf, 2);
1139  /// assert_eq!(buf.buffer(), &[1, 2]);
1140  /// assert_eq!(tail.buffer(), &[3, 4, 5]);
1141  /// ```
1142  #[must_use = "consider Chunk::truncate if you don't need the other half"]
1143  fn split_off(&mut self, at: usize) -> Self
1144  where
1145    Self: Sized;
1146
1147  /// Splits the buffer into two at the given index.
1148  ///
1149  /// This is the non-panicking version of [`split_off`](Chunk::split_off).
1150  /// Returns `Some((left, right))` if `at <= self.remaining()`, otherwise returns `None`.
1151  ///
1152  /// # Examples
1153  ///
1154  /// ```rust
1155  /// use bufkit::Chunk;
1156  ///
1157  /// let data = [1, 2, 3, 4, 5];
1158  /// let mut buf = &data[..];
1159  ///
1160  /// assert!(Chunk::split_off_checked(&mut buf, 2).is_some());
1161  ///
1162  /// let mut small_buf = &[1u8][..];
1163  /// assert!(Chunk::split_off_checked(&mut small_buf, 5).is_none());
1164  /// ```
1165  #[must_use = "consider Chunk::truncate if you don't need the other half"]
1166  fn split_off_checked(&mut self, at: usize) -> Option<Self>
1167  where
1168    Self: Sized,
1169  {
1170    if at > self.remaining() {
1171      None
1172    } else {
1173      Some(self.split_off(at))
1174    }
1175  }
1176
1177  /// Splits the buffer into two at the given index.
1178  ///
1179  /// This is the non-panicking version of [`split_off`](Chunk::split_off) that
1180  /// returns detailed error information on failure.
1181  /// Returns `Ok(right_half)` on success, or `Err(OutOfBounds)` with details about
1182  /// the attempted split position and available bytes.
1183  ///
1184  /// # Examples
1185  ///
1186  /// ```rust
1187  /// use bufkit::Chunk;
1188  ///
1189  /// let data = [1, 2, 3, 4, 5];
1190  /// let mut buf = &data[..];
1191  ///
1192  /// assert!(Chunk::try_split_off(&mut buf, 2).is_ok());
1193  ///
1194  /// let mut small_buf = &[1u8][..];
1195  /// let err = Chunk::try_split_off(&mut small_buf, 5).unwrap_err();
1196  /// // err contains details about requested vs available
1197  /// ```
1198  #[must_use = "consider Chunk::try_split_off if you don't need the other half"]
1199  fn try_split_off(&mut self, at: usize) -> Result<Self, OutOfBounds>
1200  where
1201    Self: Sized,
1202  {
1203    if at > self.remaining() {
1204      Err(OutOfBounds::new(at, self.remaining()))
1205    } else {
1206      Ok(self.split_off(at))
1207    }
1208  }
1209
1210  /// Splits the buffer into two at the given index.
1211  ///
1212  /// Afterwards `self` contains elements `[at, remaining())`, and the returned
1213  /// buffer contains elements `[0, at)`.
1214  ///
1215  /// **Implementor Notes:** This should be an `O(1)` operation.
1216  ///
1217  /// # Panics
1218  ///
1219  /// Panics if `at > self.remaining()`.
1220  /// Use [`split_to_checked`](Chunk::split_to_checked) or
1221  /// [`try_split_to`](Chunk::try_split_to) for non-panicking splits.
1222  ///
1223  /// # Examples
1224  ///
1225  /// ```rust
1226  /// use bufkit::Chunk;
1227  ///
1228  /// let data = b"hello world";
1229  /// let mut buf = &data[..];
1230  ///
1231  /// let hello = buf.split_to(5);
1232  /// assert_eq!(hello.buffer(), b"hello");
1233  /// assert_eq!(buf.buffer(), b" world");
1234  /// ```
1235  #[must_use = "consider Chunk::advance if you don't need the other half"]
1236  fn split_to(&mut self, at: usize) -> Self
1237  where
1238    Self: Sized;
1239
1240  /// Splits the buffer into two at the given index.
1241  ///
1242  /// This is the non-panicking version of [`split_to`](Chunk::split_to).
1243  /// Returns `Some(left_half)` if `at <= self.remaining()`, otherwise returns `None`.
1244  ///
1245  /// # Examples
1246  ///
1247  /// ```rust
1248  /// use bufkit::Chunk;
1249  ///
1250  /// let data = [1, 2, 3, 4, 5];
1251  /// let mut buf = &data[..];
1252  ///
1253  /// assert!(Chunk::split_to_checked(&mut buf, 3).is_some());
1254  /// assert!(Chunk::split_to_checked(&mut buf, 10).is_none());
1255  /// ```
1256  #[must_use = "consider Chunk::advance if you don't need the other half"]
1257  fn split_to_checked(&mut self, at: usize) -> Option<Self>
1258  where
1259    Self: Sized,
1260  {
1261    if at > self.remaining() {
1262      None
1263    } else {
1264      Some(self.split_to(at))
1265    }
1266  }
1267
1268  /// Splits the buffer into two at the given index.
1269  ///
1270  /// This is the non-panicking version of [`split_to`](Chunk::split_to) that
1271  /// returns detailed error information on failure.
1272  /// Returns `Ok(left_half)` on success, or `Err(OutOfBounds)` with details about
1273  /// the attempted split position and available bytes.
1274  ///
1275  /// # Examples
1276  ///
1277  /// ```rust
1278  /// use bufkit::Chunk;
1279  ///
1280  /// let data = [1, 2, 3, 4, 5];
1281  /// let mut buf = &data[..];
1282  ///
1283  /// assert!(Chunk::try_split_to(&mut buf, 3).is_ok());
1284  ///
1285  /// let err = Chunk::try_split_to(&mut buf, 10).unwrap_err();
1286  /// // err contains detailed information about the failure
1287  /// ```
1288  #[must_use = "consider Chunk::try_split_to if you don't need the other half"]
1289  fn try_split_to(&mut self, at: usize) -> Result<Self, OutOfBounds>
1290  where
1291    Self: Sized,
1292  {
1293    if at > self.remaining() {
1294      Err(OutOfBounds::new(at, self.remaining()))
1295    } else {
1296      Ok(self.split_to(at))
1297    }
1298  }
1299
1300  /// Returns `true` if there are bytes available for reading in the buffer.
1301  ///
1302  /// This is equivalent to `self.remaining() > 0`.
1303  ///
1304  /// # Examples
1305  ///
1306  /// ```rust
1307  /// use bufkit::Chunk;
1308  ///
1309  /// let data = [1, 2, 3];
1310  /// let mut buf = &data[..];
1311  /// assert!(Chunk::has_remaining(&buf));
1312  ///
1313  /// buf.advance(3);
1314  /// assert!(!Chunk::has_remaining(&buf));
1315  /// ```
1316  fn has_remaining(&self) -> bool {
1317    self.remaining() > 0
1318  }
1319
1320  /// Attempts to advance the internal cursor by the specified number of bytes.
1321  ///
1322  /// This is the non-panicking version of [`advance`](Chunk::advance).
1323  /// Returns `Ok(())` if the advancement was successful, or `Err(TryAdvanceError)`
1324  /// with details about requested vs available bytes.
1325  ///
1326  /// # Examples
1327  ///
1328  /// ```rust
1329  /// use bufkit::Chunk;
1330  ///
1331  /// let data = [1, 2, 3, 4, 5];
1332  /// let mut buf = &data[..];
1333  ///
1334  /// assert!(buf.try_advance(3).is_ok());
1335  /// assert_eq!(buf.remaining(), 2);
1336  ///
1337  /// let err = buf.try_advance(5).unwrap_err();
1338  /// // err contains details about requested vs available
1339  /// ```
1340  fn try_advance(&mut self, cnt: usize) -> Result<(), TryAdvanceError> {
1341    if cnt == 0 {
1342      return Ok(());
1343    }
1344
1345    let remaining = self.remaining();
1346    if remaining < cnt {
1347      return Err(TryAdvanceError::new(must_non_zero(cnt), remaining));
1348    }
1349
1350    self.advance(cnt);
1351    Ok(())
1352  }
1353
1354  /// Attempts to create a new buffer containing a segment of the current buffer's data.
1355  ///
1356  /// The returned buffer is independent with its own cursor starting at the beginning of the segment.
1357  /// The original buffer remains unchanged. This is the non-panicking version of
1358  /// [`segment`](Chunk::segment).
1359  ///
1360  /// Returns `Ok(segment)` if the range is valid, or `Err(TrySegmentError)` if the range
1361  /// extends beyond the current buffer's available data.
1362  ///
1363  /// # Examples
1364  ///
1365  /// ```rust
1366  /// use bufkit::Chunk;
1367  ///
1368  /// let data = b"Hello, World!";
1369  /// let buf = &data[..];
1370  ///
1371  /// assert!(buf.try_segment(0..5).is_ok());
1372  /// assert!(buf.try_segment(0..20).is_err()); // Out of bounds
1373  /// ```
1374  #[inline]
1375  fn try_segment(&self, range: impl RangeBounds<usize>) -> Result<Self, TrySegmentError>
1376  where
1377    Self: Sized,
1378  {
1379    check_segment(range, self.remaining()).map(|(start, end)| self.segment(start..end))
1380  }
1381
1382  // Macro generates peek methods for primitive types
1383  peek_fixed!(u16, u32, u64, u128, i16, i32, i64, i128, f32, f64);
1384
1385  // Macro generates read methods for primitive types
1386  read_fixed!(u16, u32, u64, u128, i16, i32, i64, i128, f32, f64);
1387
1388  /// Peeks a `u8` value from the buffer without advancing the internal cursor.
1389  ///
1390  /// Returns the first byte from the buffer without consuming it.
1391  /// The buffer position remains unchanged after this operation.
1392  ///
1393  /// # Panics
1394  ///
1395  /// Panics if the buffer is empty.
1396  /// Use [`peek_u8_checked`](Chunk::peek_u8_checked) for non-panicking peeks.
1397  ///
1398  /// # Examples
1399  ///
1400  /// ```rust
1401  /// use bufkit::Chunk;
1402  ///
1403  /// let data = [42, 1, 2, 3];
1404  /// let buf = &data[..];
1405  ///
1406  /// assert_eq!(buf.peek_u8(), 42);
1407  /// assert_eq!(buf.remaining(), 4); // Unchanged
1408  /// ```
1409  #[inline]
1410  fn peek_u8(&self) -> u8 {
1411    self.buffer()[0]
1412  }
1413
1414  /// Peeks a `u8` value from the buffer without advancing the internal cursor.
1415  ///
1416  /// This is the non-panicking version of [`peek_u8`](Chunk::peek_u8).
1417  /// Returns `Some(byte)` if data is available, otherwise returns `None`.
1418  ///
1419  /// # Examples
1420  ///
1421  /// ```rust
1422  /// use bufkit::Chunk;
1423  ///
1424  /// let data = [42];
1425  /// let buf = &data[..];
1426  /// assert_eq!(buf.peek_u8_checked(), Some(42));
1427  ///
1428  /// let empty_buf = &[][..];
1429  /// assert_eq!(empty_buf.peek_u8_checked(), None);
1430  /// ```
1431  #[inline]
1432  fn peek_u8_checked(&self) -> Option<u8> {
1433    self.buffer().first().copied()
1434  }
1435
1436  /// Peeks a `u8` value from the buffer without advancing the internal cursor.
1437  ///
1438  /// This is the non-panicking version of [`peek_u8`](Chunk::peek_u8).
1439  /// Returns `Ok(byte)` if data is available, otherwise returns `Err`.
1440  ///
1441  /// # Examples
1442  ///
1443  /// ```rust
1444  /// use bufkit::Chunk;
1445  ///
1446  /// let data = [42];
1447  /// let buf = &data[..];
1448  /// assert_eq!(buf.peek_u8_checked(), Some(42));
1449  ///
1450  /// let empty_buf = &[][..];
1451  /// assert!(empty_buf.try_peek_u8().is_err());
1452  /// ```
1453  #[inline]
1454  fn try_peek_u8(&self) -> Result<u8, TryPeekError> {
1455    self
1456      .buffer()
1457      .first()
1458      .copied()
1459      .ok_or_else(|| TryPeekError::new(super::NON_ZERO_1, self.remaining()))
1460  }
1461
1462  /// Peeks a `u8` value from the buffer at the specified offset without advancing the cursor.
1463  ///
1464  /// Returns the byte at the given offset without consuming it.
1465  /// The buffer position remains unchanged after this operation.
1466  ///
1467  /// # Panics
1468  ///
1469  /// Panics if `offset >= self.remaining()`.
1470  /// Use [`peek_u8_at_checked`](Chunk::peek_u8_at_checked) for non-panicking peeks.
1471  ///
1472  /// # Examples
1473  ///
1474  /// ```rust
1475  /// use bufkit::Chunk;
1476  ///
1477  /// let data = [42, 1, 2, 3];
1478  /// let buf = &data[..];
1479  ///
1480  /// assert_eq!(buf.peek_u8_at(0), 42);
1481  /// assert_eq!(buf.peek_u8_at(2), 2);
1482  /// assert_eq!(buf.remaining(), 4); // Unchanged
1483  /// ```
1484  #[inline]
1485  fn peek_u8_at(&self, offset: usize) -> u8 {
1486    self.buffer_from(offset)[0]
1487  }
1488
1489  /// Peeks a `u8` value from the buffer at the specified offset without advancing the cursor.
1490  ///
1491  /// This is the non-panicking version of [`peek_u8_at`](Chunk::peek_u8_at).
1492  /// Returns `Some(byte)` if the offset is valid, otherwise returns `None`.
1493  ///
1494  /// # Examples
1495  ///
1496  /// ```rust
1497  /// use bufkit::Chunk;
1498  ///
1499  /// let data = [42, 1, 2];
1500  /// let buf = &data[..];
1501  /// assert_eq!(buf.peek_u8_at_checked(1), Some(1));
1502  /// assert_eq!(buf.peek_u8_at_checked(10), None);
1503  /// ```
1504  #[inline]
1505  fn peek_u8_at_checked(&self, offset: usize) -> Option<u8> {
1506    self.buffer().get(offset).copied()
1507  }
1508
1509  /// Peeks a `u8` value from the buffer at the specified offset without advancing the cursor.
1510  ///
1511  /// This is the non-panicking version of [`peek_u8_at`](Chunk::peek_u8_at).
1512  /// Returns `Ok(byte)` if the offset is valid, otherwise returns `Err(TryPeekAtError)`.
1513  ///
1514  /// # Examples
1515  ///
1516  /// ```rust
1517  /// use bufkit::Chunk;
1518  ///
1519  /// let data = [42, 1, 2];
1520  /// let buf = &data[..];
1521  /// assert_eq!(buf.try_peek_u8_at(1), Ok(1));
1522  ///
1523  /// let err = buf.try_peek_u8_at(10).unwrap_err();
1524  /// // err contains details about the error
1525  /// ```
1526  #[inline]
1527  fn try_peek_u8_at(&self, offset: usize) -> Result<u8, TryPeekAtError> {
1528    let buffer = self.buffer();
1529
1530    if offset >= buffer.len() {
1531      return Err(TryPeekAtError::out_of_bounds(offset, buffer.len()));
1532    }
1533
1534    Ok(buffer[offset])
1535  }
1536
1537  /// Peeks an `i8` value from the buffer at the specified offset without advancing the cursor.
1538  ///
1539  /// Returns the byte at the given offset as a signed integer without consuming it.
1540  /// The buffer position remains unchanged after this operation.
1541  ///
1542  /// # Panics
1543  ///
1544  /// Panics if `offset >= self.remaining()`.
1545  /// Use [`peek_i8_at_checked`](Chunk::peek_i8_at_checked) for non-panicking peeks.
1546  ///
1547  /// # Examples
1548  ///
1549  /// ```rust
1550  /// use bufkit::Chunk;
1551  ///
1552  /// let data = [255u8, 1, 2, 3]; // 255 as i8 is -1
1553  /// let buf = &data[..];
1554  ///
1555  /// assert_eq!(buf.peek_i8_at(0), -1);
1556  /// assert_eq!(buf.remaining(), 4); // Unchanged
1557  /// ```
1558  #[inline]
1559  fn peek_i8_at(&self, offset: usize) -> i8 {
1560    self.peek_u8_at(offset) as i8
1561  }
1562
1563  /// Peeks an `i8` value from the buffer at the specified offset without advancing the cursor.
1564  ///
1565  /// This is the non-panicking version of [`peek_i8_at`](Chunk::peek_i8_at).
1566  /// Returns `Some(byte)` if the offset is valid, otherwise returns `None`.
1567  ///
1568  /// # Examples
1569  ///
1570  /// ```rust
1571  /// use bufkit::Chunk;
1572  ///
1573  /// let data = [255u8, 1, 2]; // 255 as i8 is -1
1574  /// let buf = &data[..];
1575  /// assert_eq!(buf.peek_i8_at_checked(0), Some(-1));
1576  /// assert_eq!(buf.peek_i8_at_checked(10), None);
1577  /// ```
1578  #[inline]
1579  fn peek_i8_at_checked(&self, offset: usize) -> Option<i8> {
1580    self.peek_u8_at_checked(offset).map(|v| v as i8)
1581  }
1582
1583  /// Peeks an `i8` value from the buffer at the specified offset without advancing the cursor.
1584  ///
1585  /// This is the non-panicking version of [`peek_i8_at`](Chunk::peek_i8_at).
1586  /// Returns `Ok(byte)` if the offset is valid, otherwise returns `Err(TryPeekAtError)`.
1587  ///
1588  /// # Examples
1589  ///
1590  /// ```rust
1591  /// use bufkit::Chunk;
1592  ///
1593  /// let data = [255u8, 1, 2]; // 255 as i8 is -1
1594  /// let buf = &data[..];
1595  /// assert_eq!(buf.try_peek_i8_at(0), Ok(-1));
1596  ///
1597  /// let err = buf.try_peek_i8_at(10).unwrap_err();
1598  /// // err contains details about the error
1599  /// ```
1600  #[inline]
1601  fn try_peek_i8_at(&self, offset: usize) -> Result<i8, TryPeekAtError> {
1602    self.try_peek_u8_at(offset).map(|v| v as i8)
1603  }
1604
1605  /// Reads a `u8` value from the buffer and advances the internal cursor.
1606  ///
1607  /// Returns the first byte from the buffer and advances the cursor by 1 byte.
1608  ///
1609  /// # Panics
1610  ///
1611  /// Panics if the buffer is empty.
1612  /// Use [`read_u8_checked`](Chunk::read_u8_checked) for non-panicking reads.
1613  ///
1614  /// # Examples
1615  ///
1616  /// ```rust
1617  /// use bufkit::Chunk;
1618  ///
1619  /// let data = [42, 1, 2, 3];
1620  /// let mut buf = &data[..];
1621  ///
1622  /// assert_eq!(buf.read_u8(), 42);
1623  /// assert_eq!(buf.remaining(), 3); // Cursor advanced
1624  /// ```
1625  #[inline]
1626  fn read_u8(&mut self) -> u8 {
1627    let val = self.peek_u8();
1628    self.advance(1);
1629    val
1630  }
1631
1632  /// Reads a `u8` value from the buffer and advances the internal cursor.
1633  ///
1634  /// This is the non-panicking version of [`read_u8`](Chunk::read_u8).
1635  /// Returns `Some(byte)` and advances the cursor on success, or `None` if the buffer is empty.
1636  ///
1637  /// # Examples
1638  ///
1639  /// ```rust
1640  /// use bufkit::Chunk;
1641  ///
1642  /// let data = [42];
1643  /// let mut buf = &data[..];
1644  ///
1645  /// assert_eq!(buf.read_u8_checked(), Some(42));
1646  /// assert_eq!(buf.remaining(), 0);
1647  ///
1648  /// assert_eq!(buf.read_u8_checked(), None); // Empty now
1649  /// ```
1650  #[inline]
1651  fn read_u8_checked(&mut self) -> Option<u8> {
1652    self.peek_u8_checked().inspect(|_| {
1653      self.advance(1);
1654    })
1655  }
1656
1657  /// Reads a `u8` value from the buffer and advances the internal cursor.
1658  ///
1659  /// This is the non-panicking version of [`read_u8`](Chunk::read_u8).
1660  /// Returns `Ok(byte)` and advances the cursor on success, or `Err` if the buffer is empty.
1661  ///
1662  /// # Examples
1663  ///
1664  /// ```rust
1665  /// use bufkit::Chunk;
1666  ///
1667  /// let data = [42];
1668  /// let mut buf = &data[..];
1669  ///
1670  /// assert_eq!(buf.read_u8_checked(), Some(42));
1671  /// assert_eq!(buf.remaining(), 0);
1672  ///
1673  /// assert!(buf.try_read_u8().is_err()); // Empty now
1674  /// ```
1675  #[inline]
1676  fn try_read_u8(&mut self) -> Result<u8, TryReadError> {
1677    self
1678      .read_u8_checked()
1679      .ok_or_else(|| TryReadError::new(super::NON_ZERO_1, self.remaining()))
1680  }
1681
1682  /// Peeks an `i8` value from the buffer without advancing the internal cursor.
1683  ///
1684  /// Returns the first byte from the buffer as a signed integer without consuming it.
1685  /// The buffer position remains unchanged after this operation.
1686  ///
1687  /// # Panics
1688  ///
1689  /// Panics if the buffer is empty.
1690  /// Use [`peek_i8_checked`](Chunk::peek_i8_checked) for non-panicking peeks.
1691  ///
1692  /// # Examples
1693  ///
1694  /// ```rust
1695  /// use bufkit::Chunk;
1696  ///
1697  /// let data = [255u8, 1, 2, 3]; // 255 as i8 is -1
1698  /// let buf = &data[..];
1699  ///
1700  /// assert_eq!(buf.peek_i8(), -1);
1701  /// assert_eq!(buf.remaining(), 4); // Unchanged
1702  /// ```
1703  #[inline]
1704  fn peek_i8(&self) -> i8 {
1705    self.peek_u8() as i8
1706  }
1707
1708  /// Peeks an `i8` value from the buffer without advancing the internal cursor.
1709  ///
1710  /// This is the non-panicking version of [`peek_i8`](Chunk::peek_i8).
1711  /// Returns `Some(byte)` if data is available, otherwise returns `None`.
1712  ///
1713  /// # Examples
1714  ///
1715  /// ```rust
1716  /// use bufkit::Chunk;
1717  ///
1718  /// let data = [255u8]; // -1 as i8
1719  /// let buf = &data[..];
1720  /// assert_eq!(buf.peek_i8_checked(), Some(-1));
1721  ///
1722  /// let empty_buf = &[][..];
1723  /// assert_eq!(empty_buf.peek_i8_checked(), None);
1724  /// ```
1725  #[inline]
1726  fn peek_i8_checked(&self) -> Option<i8> {
1727    self.peek_u8_checked().map(|v| v as i8)
1728  }
1729
1730  /// Peeks an `i8` value from the buffer without advancing the internal cursor.
1731  ///
1732  /// This is the non-panicking version of [`peek_i8`](Chunk::peek_i8).
1733  /// Returns `Ok(byte)` if data is available, otherwise returns `Err`.
1734  ///
1735  /// # Examples
1736  ///
1737  /// ```rust
1738  /// use bufkit::Chunk;
1739  ///
1740  /// let data = [255u8]; // -1 as i8
1741  /// let buf = &data[..];
1742  /// assert_eq!(buf.try_peek_i8(), Ok(-1));
1743  ///
1744  /// let empty_buf = &[][..];
1745  /// assert!(empty_buf.try_peek_i8().is_err());
1746  /// ```
1747  #[inline]
1748  fn try_peek_i8(&self) -> Result<i8, TryPeekError> {
1749    self.try_peek_u8().map(|v| v as i8)
1750  }
1751
1752  /// Reads an `i8` value from the buffer and advances the internal cursor.
1753  ///
1754  /// Returns the first byte from the buffer as a signed integer and advances the cursor by 1 byte.
1755  ///
1756  /// # Panics
1757  ///
1758  /// Panics if the buffer is empty.
1759  /// Use [`read_i8_checked`](Chunk::read_i8_checked) for non-panicking reads.
1760  ///
1761  /// # Examples
1762  ///
1763  /// ```rust
1764  /// use bufkit::Chunk;
1765  ///
1766  /// let data = [255u8, 1, 2, 3]; // 255 as i8 is -1
1767  /// let mut buf = &data[..];
1768  ///
1769  /// assert_eq!(buf.read_i8(), -1);
1770  /// assert_eq!(buf.remaining(), 3); // Cursor advanced
1771  /// ```
1772  #[inline]
1773  fn read_i8(&mut self) -> i8 {
1774    self.read_u8() as i8
1775  }
1776
1777  /// Reads an `i8` value from the buffer and advances the internal cursor.
1778  ///
1779  /// This is the non-panicking version of [`read_i8`](Chunk::read_i8).
1780  /// Returns `Some(byte)` and advances the cursor on success, or `None` if the buffer is empty.
1781  ///
1782  /// # Examples
1783  ///
1784  /// ```rust
1785  /// use bufkit::Chunk;
1786  ///
1787  /// let data = [255u8]; // -1 as i8
1788  /// let mut buf = &data[..];
1789  ///
1790  /// assert_eq!(buf.read_i8_checked(), Some(-1));
1791  /// assert_eq!(buf.remaining(), 0);
1792  ///
1793  /// assert_eq!(buf.read_i8_checked(), None); // Empty now
1794  /// ```
1795  #[inline]
1796  fn read_i8_checked(&mut self) -> Option<i8> {
1797    self.read_u8_checked().map(|v| v as i8)
1798  }
1799
1800  /// Reads an `i8` value from the buffer and advances the internal cursor.
1801  ///
1802  /// This is the non-panicking version of [`read_i8`](Chunk::read_i8).
1803  /// Returns `Ok(byte)` and advances the cursor on success, or `Err(Try
1804  /// ReadError)` if the buffer is empty.
1805  ///
1806  /// # Examples
1807  /// ```rust
1808  /// use bufkit::Chunk;
1809  ///
1810  /// let data = [255u8]; // -1 as i8
1811  /// let mut buf = &data[..];
1812  /// assert_eq!(buf.try_read_i8(), Ok(-1));
1813  /// assert_eq!(buf.remaining(), 0);
1814  /// assert!(buf.try_read_i8().is_err()); // Empty now
1815  /// ```
1816  #[inline]
1817  fn try_read_i8(&mut self) -> Result<i8, TryReadError> {
1818    self.try_read_u8().map(|v| v as i8)
1819  }
1820
1821  /// Converts the read buffer to a `Vec<u8>` instance.
1822  ///
1823  /// Creates a new vector containing a copy of all available bytes in the buffer.
1824  /// The original buffer remains unchanged.
1825  ///
1826  /// # Examples
1827  ///
1828  /// ```rust
1829  /// use bufkit::Chunk;
1830  ///
1831  /// let data = [1, 2, 3, 4, 5];
1832  /// let buf = &data[..];
1833  ///
1834  /// let vec = buf.to_vec();
1835  /// assert_eq!(vec, vec![1, 2, 3, 4, 5]);
1836  /// ```
1837  #[cfg(any(feature = "std", feature = "alloc"))]
1838  #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
1839  fn to_vec(&self) -> ::std::vec::Vec<u8> {
1840    self.buffer().to_vec()
1841  }
1842
1843  /// Converts the read buffer to a `Bytes` instance.
1844  ///
1845  /// Creates a new `Bytes` instance containing a copy of all available bytes in the buffer.
1846  /// The original buffer remains unchanged.
1847  #[cfg(all(feature = "bytes_1", any(feature = "std", feature = "alloc")))]
1848  #[cfg_attr(
1849    docsrs,
1850    doc(cfg(all(feature = "bytes_1", any(feature = "std", feature = "alloc"))))
1851  )]
1852  fn to_bytes(&self) -> ::bytes_1::Bytes {
1853    ::bytes_1::Bytes::copy_from_slice(self.buffer())
1854  }
1855
1856  /// Converts the read buffer to a `BytesMut` instance.
1857  ///
1858  /// Creates a new `BytesMut` instance containing a copy of all available bytes in the buffer.
1859  /// The original buffer remains unchanged.
1860  #[cfg(all(feature = "bytes_1", any(feature = "std", feature = "alloc")))]
1861  #[cfg_attr(
1862    docsrs,
1863    doc(cfg(all(feature = "bytes_1", any(feature = "std", feature = "alloc"))))
1864  )]
1865  #[allow(clippy::wrong_self_convention)]
1866  fn to_bytes_mut(&self) -> ::bytes_1::BytesMut {
1867    ::bytes_1::BytesMut::from(self.to_bytes())
1868  }
1869}
1870
1871/// Extension trait for `Chunk` that provides additional methods
1872pub trait ChunkExt: Chunk {
1873  /// Peeks a fixed-size array from the beginning of the buffer without advancing the cursor.
1874  ///
1875  /// This method creates a copy of the first `N` bytes from the buffer without
1876  /// consuming them. The buffer position remains unchanged after this operation.
1877  ///
1878  /// # Panics
1879  ///
1880  /// Panics if the buffer contains fewer than `N` bytes.
1881  /// Use [`peek_array_checked`](Chunk::peek_array_checked) or
1882  /// [`try_peek_array`](Chunk::try_peek_array) for non-panicking peeks.
1883  ///
1884  /// # Examples
1885  ///
1886  /// ```rust
1887  /// use bufkit::{Chunk, ChunkExt};
1888  ///
1889  /// let data = [1, 2, 3, 4, 5];
1890  /// let buf = &data[..];
1891  ///
1892  /// let first_three: [u8; 3] = buf.peek_array();
1893  /// assert_eq!(first_three, [1, 2, 3]);
1894  /// // Chunkfer unchanged
1895  /// assert_eq!(buf.remaining(), 5);
1896  /// ```
1897  #[inline]
1898  fn peek_array<const N: usize>(&self) -> [u8; N] {
1899    peek_array::<_, N>(self)
1900  }
1901
1902  /// Peeks a fixed-size array from the beginning of the buffer without advancing the cursor.
1903  ///
1904  /// This is the non-panicking version of [`peek_array`](Chunk::peek_array).
1905  /// Returns `Some(array)` if sufficient data is available, otherwise returns `None`.
1906  ///
1907  /// # Examples
1908  ///
1909  /// ```rust
1910  /// use bufkit::{Chunk, ChunkExt};
1911  ///
1912  /// let data = [1, 2, 3];
1913  /// let buf = &data[..];
1914  ///
1915  /// assert!(buf.peek_array_checked::<2>().is_some());
1916  /// assert!(buf.peek_array_checked::<5>().is_none());
1917  /// ```
1918  #[inline]
1919  fn peek_array_checked<const N: usize>(&self) -> Option<[u8; N]> {
1920    peek_array_checked::<_, N>(self)
1921  }
1922
1923  /// Peeks a fixed-size array from the beginning of the buffer without advancing the cursor.
1924  ///
1925  /// This is the non-panicking version of [`peek_array`](Chunk::peek_array) that
1926  /// returns detailed error information on failure.
1927  /// Returns `Ok(array)` on success, or `Err(TryPeekError)` with details about
1928  /// requested vs available bytes.
1929  ///
1930  /// # Examples
1931  ///
1932  /// ```rust
1933  /// use bufkit::{Chunk, ChunkExt};
1934  ///
1935  /// let data = [1, 2, 3];
1936  /// let buf = &data[..];
1937  ///
1938  /// assert!(buf.try_peek_array::<2>().is_ok());
1939  ///
1940  /// let err = buf.try_peek_array::<5>().unwrap_err();
1941  /// // err contains details about requested vs available
1942  /// ```
1943  #[inline]
1944  fn try_peek_array<const N: usize>(&self) -> Result<[u8; N], TryPeekError> {
1945    try_peek_array::<_, N>(self)
1946  }
1947
1948  /// Peeks a fixed-size array from the buffer at the specified offset without advancing the cursor.
1949  ///
1950  /// This method creates a copy of `N` bytes from the buffer starting at the given offset
1951  /// without consuming them. The buffer position remains unchanged after this operation.
1952  ///
1953  /// # Panics
1954  ///
1955  /// Panics if `offset + N > self.remaining()`.
1956  /// Use [`peek_array_at_checked`](ChunkExt::peek_array_at_checked) or
1957  /// [`try_peek_array_at`](ChunkExt::try_peek_array_at) for non-panicking peeks.
1958  ///
1959  /// # Examples
1960  ///
1961  /// ```rust
1962  /// use bufkit::{Chunk, ChunkExt};
1963  ///
1964  /// let data = [1, 2, 3, 4, 5, 6, 7, 8];
1965  /// let buf = &data[..];
1966  ///
1967  /// let array_at_2: [u8; 3] = buf.peek_array_at(2);
1968  /// assert_eq!(array_at_2, [3, 4, 5]);
1969  /// // Chunkfer unchanged
1970  /// assert_eq!(buf.remaining(), 8);
1971  /// ```
1972  #[inline]
1973  fn peek_array_at<const N: usize>(&self, offset: usize) -> [u8; N] {
1974    peek_array_at::<_, N>(self, offset)
1975  }
1976
1977  /// Peeks a fixed-size array from the buffer at the specified offset without advancing the cursor.
1978  ///
1979  /// This is the non-panicking version of [`peek_array_at`](ChunkExt::peek_array_at).
1980  /// Returns `Some(array)` if sufficient data is available at the offset, otherwise returns `None`.
1981  ///
1982  /// # Examples
1983  ///
1984  /// ```rust
1985  /// use bufkit::{Chunk, ChunkExt};
1986  ///
1987  /// let data = [1, 2, 3, 4, 5];
1988  /// let buf = &data[..];
1989  ///
1990  /// assert!(buf.peek_array_at_checked::<3>(1).is_some());
1991  /// assert!(buf.peek_array_at_checked::<3>(4).is_none()); // Not enough bytes
1992  /// ```
1993  #[inline]
1994  fn peek_array_at_checked<const N: usize>(&self, offset: usize) -> Option<[u8; N]> {
1995    peek_array_at_checked::<_, N>(self, offset)
1996  }
1997
1998  /// Peeks a fixed-size array from the buffer at the specified offset without advancing the cursor.
1999  ///
2000  /// This is the non-panicking version of [`peek_array_at`](ChunkExt::peek_array_at) that
2001  /// returns detailed error information on failure.
2002  /// Returns `Ok(array)` on success, or `Err(TryPeekAtError)` with details about
2003  /// the error condition.
2004  ///
2005  /// # Examples
2006  ///
2007  /// ```rust
2008  /// use bufkit::{Chunk, ChunkExt};
2009  ///
2010  /// let data = [1, 2, 3, 4, 5];
2011  /// let buf = &data[..];
2012  ///
2013  /// assert!(buf.try_peek_array_at::<3>(1).is_ok());
2014  ///
2015  /// let err = buf.try_peek_array_at::<3>(4).unwrap_err();
2016  /// let err = buf.try_peek_array_at::<3>(6).unwrap_err();
2017  /// // err contains details about the error
2018  /// ```
2019  #[inline]
2020  fn try_peek_array_at<const N: usize>(&self, offset: usize) -> Result<[u8; N], TryPeekAtError> {
2021    try_peek_array_at::<_, N>(self, offset)
2022  }
2023
2024  /// Reads a fixed-size array from the buffer and advances the internal cursor.
2025  ///
2026  /// This method creates a copy of the first `N` bytes from the buffer and
2027  /// advances the cursor by `N` bytes, consuming the data.
2028  ///
2029  /// # Panics
2030  ///
2031  /// Panics if the buffer contains fewer than `N` bytes.
2032  /// Use [`read_array_checked`](Chunk::read_array_checked) or
2033  /// [`try_read_array`](Chunk::try_read_array) for non-panicking reads.
2034  ///
2035  /// # Examples
2036  ///
2037  /// ```rust
2038  /// use bufkit::{Chunk, ChunkExt};
2039  ///
2040  /// let data = [1, 2, 3, 4, 5];
2041  /// let mut buf = &data[..];
2042  ///
2043  /// let first_three: [u8; 3] = buf.read_array();
2044  /// assert_eq!(first_three, [1, 2, 3]);
2045  /// assert_eq!(buf.remaining(), 2); // Cursor advanced
2046  /// ```
2047  #[inline]
2048  fn read_array<const N: usize>(&mut self) -> [u8; N] {
2049    let output = self.peek_array::<N>();
2050    self.advance(N);
2051    output
2052  }
2053
2054  /// Reads a fixed-size array from the buffer and advances the internal cursor.
2055  ///
2056  /// This is the non-panicking version of [`read_array`](Chunk::read_array).
2057  /// Returns `Some(array)` and advances the cursor on success, or `None` if insufficient data.
2058  ///
2059  /// # Examples
2060  ///
2061  /// ```rust
2062  /// use bufkit::{Chunk, ChunkExt};
2063  ///
2064  /// let data = [1, 2, 3];
2065  /// let mut buf = &data[..];
2066  ///
2067  /// assert!(buf.read_array_checked::<2>().is_some());
2068  /// assert_eq!(buf.remaining(), 1);
2069  ///
2070  /// assert!(buf.read_array_checked::<2>().is_none());
2071  /// assert_eq!(buf.remaining(), 1); // Cursor not advanced on failure
2072  /// ```
2073  #[inline]
2074  fn read_array_checked<const N: usize>(&mut self) -> Option<[u8; N]> {
2075    self.peek_array_checked::<N>().inspect(|_| {
2076      self.advance(N);
2077    })
2078  }
2079
2080  /// Reads a fixed-size array from the buffer and advances the internal cursor.
2081  ///
2082  /// This is the non-panicking version of [`read_array`](Chunk::read_array) that
2083  /// returns detailed error information on failure.
2084  /// Returns `Ok(array)` and advances the cursor on success, or `Err(TryReadError)`
2085  /// with details about requested vs available bytes.
2086  ///
2087  /// # Examples
2088  ///
2089  /// ```rust
2090  /// use bufkit::{Chunk, ChunkExt};
2091  ///
2092  /// let data = [1, 2, 3];
2093  /// let mut buf = &data[..];
2094  ///
2095  /// assert!(buf.try_read_array::<2>().is_ok());
2096  /// assert_eq!(buf.remaining(), 1);
2097  ///
2098  /// let err = buf.try_read_array::<2>().unwrap_err();
2099  /// // err contains details about requested vs available
2100  /// ```
2101  #[inline]
2102  fn try_read_array<const N: usize>(&mut self) -> Result<[u8; N], TryReadError> {
2103    self
2104      .try_peek_array::<N>()
2105      .inspect(|_| {
2106        self.advance(N);
2107      })
2108      .map_err(Into::into)
2109  }
2110
2111  /// Peeks a variable-length encoded type from the buffer without advancing the internal cursor.
2112  ///
2113  /// Returns the length of the value and the value itself.
2114  #[cfg(feature = "varint")]
2115  #[cfg_attr(docsrs, doc(cfg(feature = "varint")))]
2116  #[inline]
2117  fn peek_varint<V: Varint>(&self) -> Result<(NonZeroUsize, V), DecodeVarintError> {
2118    V::decode(self.buffer())
2119  }
2120
2121  /// Reads a variable-length encoded type from the buffer and advances the internal cursor.
2122  ///
2123  /// Returns the length of the value read and the value itself.
2124  #[cfg(feature = "varint")]
2125  #[cfg_attr(docsrs, doc(cfg(feature = "varint")))]
2126  #[inline]
2127  fn read_varint<V: Varint>(&mut self) -> Result<(NonZeroUsize, V), DecodeVarintError> {
2128    V::decode(self.buffer()).inspect(|(len, _)| {
2129      self.advance(len.get());
2130    })
2131  }
2132
2133  /// Skips a variable-length encoded type in the buffer without advancing the internal cursor.
2134  ///
2135  /// In varint encoding, each byte uses 7 bits for the value and the highest bit (MSB)
2136  /// as a continuation flag. A set MSB (1) indicates more bytes follow, while an unset MSB (0)
2137  /// marks the last byte of the varint.
2138  ///
2139  /// ## Examples
2140  ///
2141  /// ```rust
2142  /// use bufkit::{ChunkExt, Chunk};
2143  ///
2144  /// let buf = [0x96, 0x01]; // Varint encoding of 150
2145  /// let mut chunk = &buf[..];
2146  /// assert_eq!(chunk.try_scan_varint().map(|val| val.get()), Ok(2));
2147  /// assert_eq!(chunk.remaining(), 2); // Cursor not advanced
2148  ///
2149  /// let buf = [0x7F]; // Varint encoding of 127
2150  /// let mut chunk = &buf[..];
2151  /// assert_eq!(chunk.try_scan_varint().map(|val| val.get()), Ok(1));
2152  /// assert_eq!(chunk.remaining(), 1); // Cursor not advanced
2153  /// ```
2154  #[cfg(feature = "varint")]
2155  #[cfg_attr(docsrs, doc(cfg(feature = "varint")))]
2156  fn try_scan_varint(&mut self) -> Result<NonZeroUsize, DecodeVarintError> {
2157    varing::try_consume_varint(self.buffer()).map_err(Into::into)
2158  }
2159
2160  /// Skips a variable-length encoded type in the buffer at the specified offset without advancing the cursor.
2161  ///
2162  /// In varint encoding, each byte uses 7 bits for the value and the highest bit (MSB)
2163  /// as a continuation flag. A set MSB (1) indicates more bytes follow, while an unset MSB (0)
2164  /// marks the last byte of the varint.
2165  ///
2166  /// ## Examples
2167  ///
2168  /// ```rust
2169  /// use bufkit::{ChunkExt, Chunk};
2170  ///
2171  /// let buf = [0, 0x96, 0x01]; // Varint encoding of 150
2172  /// let mut chunk = &buf[..];
2173  /// assert_eq!(chunk.try_scan_varint_at(1).map(|val| val.get()), Ok(2));
2174  /// assert_eq!(chunk.remaining(), 3); // Cursor not advanced
2175  ///
2176  /// let buf = [0, 0x7F]; // Varint encoding of 127
2177  /// let mut chunk = &buf[..];
2178  /// assert_eq!(chunk.try_scan_varint_at(1).map(|val| val.get()), Ok(1));
2179  /// assert_eq!(chunk.remaining(), 2); // Cursor not advanced
2180  ///
2181  /// // Out of bounds example
2182  /// let err = chunk.try_scan_varint_at(10).unwrap_err();
2183  /// ```
2184  #[cfg(feature = "varint")]
2185  #[cfg_attr(docsrs, doc(cfg(feature = "varint")))]
2186  fn try_scan_varint_at(&mut self, offset: usize) -> Result<NonZeroUsize, DecodeVarintAtError> {
2187    self
2188      .buffer_from_checked(offset)
2189      .ok_or_else(|| DecodeVarintAtError::out_of_bounds(offset, self.remaining()))
2190      .and_then(|buf| {
2191        varing::try_consume_varint(buf)
2192          .map_err(|e| DecodeVarintAtError::from_const_varint_error(e, offset))
2193      })
2194  }
2195
2196  /// Skips a variable-length encoded type in the buffer and advances the internal cursor.
2197  ///
2198  /// In varint encoding, each byte uses 7 bits for the value and the highest bit (MSB)
2199  /// as a continuation flag. A set MSB (1) indicates more bytes follow, while an unset MSB (0)
2200  /// marks the last byte of the varint.
2201  ///
2202  /// ## Examples
2203  ///
2204  /// ```rust
2205  /// use bufkit::{ChunkExt, Chunk};
2206  ///
2207  /// let buf = [0x96, 0x01]; // Varint encoding of 150
2208  /// let mut chunk = &buf[..];
2209  /// assert_eq!(chunk.try_consume_varint().map(|val| val.get()), Ok(2));
2210  /// assert_eq!(chunk.remaining(), 0); // Cursor advanced
2211  ///
2212  /// let buf = [0x7F]; // Varint encoding of 127
2213  /// let mut chunk = &buf[..];
2214  /// assert_eq!(chunk.try_consume_varint().map(|val| val.get()), Ok(1));
2215  /// assert_eq!(chunk.remaining(), 0); // Cursor advanced
2216  /// ```
2217  #[cfg(feature = "varint")]
2218  #[cfg_attr(docsrs, doc(cfg(feature = "varint")))]
2219  fn try_consume_varint(&mut self) -> Result<NonZeroUsize, DecodeVarintError> {
2220    varing::try_consume_varint(self.buffer())
2221      .inspect(|len| {
2222        self.advance(len.get());
2223      })
2224      .map_err(Into::into)
2225  }
2226}
2227
2228impl<T: Chunk> ChunkExt for T {}
2229
2230#[allow(unused)]
2231macro_rules! deref_forward_buf {
2232  () => {
2233    #[inline]
2234    fn remaining(&self) -> usize {
2235      (**self).remaining()
2236    }
2237
2238    #[inline]
2239    fn has_remaining(&self) -> bool {
2240      (**self).has_remaining()
2241    }
2242
2243    #[inline]
2244    fn buffer(&self) -> &[u8] {
2245      (**self).buffer()
2246    }
2247
2248    #[inline]
2249    fn buffer_from(&self, offset: usize) -> &[u8] {
2250      (**self).buffer_from(offset)
2251    }
2252
2253    #[inline]
2254    fn buffer_from_checked(&self, offset: usize) -> Option<&[u8]> {
2255      (**self).buffer_from_checked(offset)
2256    }
2257
2258    #[inline]
2259    fn advance(&mut self, cnt: usize) {
2260      (**self).advance(cnt);
2261    }
2262
2263    #[inline]
2264    fn try_advance(&mut self, cnt: usize) -> Result<(), TryAdvanceError> {
2265      (**self).try_advance(cnt)
2266    }
2267
2268    #[inline]
2269    fn prefix(&self, len: usize) -> &[u8] {
2270      (**self).prefix(len)
2271    }
2272
2273    #[inline]
2274    fn prefix_checked(&self, len: usize) -> Option<&[u8]> {
2275      (**self).prefix_checked(len)
2276    }
2277
2278    #[inline]
2279    fn suffix(&self, len: usize) -> &[u8] {
2280      (**self).suffix(len)
2281    }
2282
2283    #[inline]
2284    fn suffix_checked(&self, len: usize) -> Option<&[u8]> {
2285      (**self).suffix_checked(len)
2286    }
2287
2288    #[inline]
2289    fn segment(&self, range: impl RangeBounds<usize>) -> Self
2290    where
2291      Self: Sized,
2292    {
2293      (**self).segment(range)
2294    }
2295
2296    #[inline]
2297    fn try_segment(&self, range: impl RangeBounds<usize>) -> Result<Self, TrySegmentError>
2298    where
2299      Self: Sized,
2300    {
2301      (**self).try_segment(range)
2302    }
2303
2304    #[inline]
2305    fn truncate(&mut self, len: usize) {
2306      (**self).truncate(len);
2307    }
2308
2309    #[inline]
2310    fn split_off(&mut self, at: usize) -> Self
2311    where
2312      Self: Sized,
2313    {
2314      (**self).split_off(at)
2315    }
2316
2317    #[inline]
2318    fn split_off_checked(&mut self, at: usize) -> Option<Self>
2319    where
2320      Self: Sized,
2321    {
2322      (**self).split_off_checked(at)
2323    }
2324
2325    #[inline]
2326    fn try_split_off(&mut self, at: usize) -> Result<Self, OutOfBounds>
2327    where
2328      Self: Sized,
2329    {
2330      (**self).try_split_off(at)
2331    }
2332
2333    #[inline]
2334    fn split_to(&mut self, at: usize) -> Self
2335    where
2336      Self: Sized,
2337    {
2338      (**self).split_to(at)
2339    }
2340
2341    #[inline]
2342    fn split_to_checked(&mut self, at: usize) -> Option<Self>
2343    where
2344      Self: Sized,
2345    {
2346      (**self).split_to_checked(at)
2347    }
2348
2349    #[inline]
2350    fn try_split_to(&mut self, at: usize) -> Result<Self, OutOfBounds>
2351    where
2352      Self: Sized,
2353    {
2354      (**self).try_split_to(at)
2355    }
2356
2357    peek_fixed!(@forward u16, u32, u64, u128, i16, i32, i64, i128, f32, f64);
2358    read_fixed!(@forward u16, u32, u64, u128, i16, i32, i64, i128, f32, f64);
2359
2360    #[inline]
2361    fn peek_u8(&self) -> u8 {
2362      (**self).peek_u8()
2363    }
2364
2365    #[inline]
2366    fn peek_u8_checked(&self) -> Option<u8> {
2367      (**self).peek_u8_checked()
2368    }
2369
2370    #[inline]
2371    fn try_peek_u8(&self) -> Result<u8, TryPeekError> {
2372      (**self).try_peek_u8()
2373    }
2374
2375    #[inline]
2376    fn read_u8(&mut self) -> u8 {
2377      (**self).read_u8()
2378    }
2379
2380    #[inline]
2381    fn read_u8_checked(&mut self) -> Option<u8> {
2382      (**self).read_u8_checked()
2383    }
2384
2385    #[inline]
2386    fn try_read_u8(&mut self) -> Result<u8, TryReadError>
2387    {
2388      (**self).try_read_u8()
2389    }
2390
2391    #[inline]
2392    fn peek_i8(&self) -> i8 {
2393      (**self).peek_i8()
2394    }
2395
2396    #[inline]
2397    fn peek_i8_checked(&self) -> Option<i8> {
2398      (**self).peek_i8_checked()
2399    }
2400
2401    #[inline]
2402    fn try_peek_i8(&self) -> Result<i8, TryPeekError>
2403    {
2404      (**self).try_peek_i8()
2405    }
2406
2407    #[inline]
2408    fn read_i8(&mut self) -> i8 {
2409      (**self).read_i8()
2410    }
2411
2412    #[inline]
2413    fn read_i8_checked(&mut self) -> Option<i8> {
2414      (**self).read_i8_checked()
2415    }
2416
2417    #[inline]
2418    fn try_read_i8(&mut self) -> Result<i8, TryReadError> {
2419      (**self).try_read_i8()
2420    }
2421  }
2422}
2423
2424impl Chunk for &[u8] {
2425  #[inline]
2426  fn remaining(&self) -> usize {
2427    <[u8]>::len(self)
2428  }
2429
2430  #[inline]
2431  fn has_remaining(&self) -> bool {
2432    !<[u8]>::is_empty(self)
2433  }
2434
2435  #[inline]
2436  fn advance(&mut self, cnt: usize) {
2437    if self.len() < cnt {
2438      panic_advance(&TryAdvanceError::new(must_non_zero(cnt), self.len()));
2439    }
2440
2441    *self = &self[cnt..];
2442  }
2443
2444  #[inline]
2445  fn try_advance(&mut self, cnt: usize) -> Result<(), TryAdvanceError> {
2446    if self.len() < cnt {
2447      return Err(TryAdvanceError::new(must_non_zero(cnt), self.len()));
2448    }
2449
2450    *self = &self[cnt..];
2451    Ok(())
2452  }
2453
2454  #[inline]
2455  fn truncate(&mut self, len: usize) {
2456    if len > self.len() {
2457      return;
2458    }
2459
2460    *self = &self[..len];
2461  }
2462
2463  #[inline]
2464  fn segment(&self, range: impl RangeBounds<usize>) -> Self {
2465    let len = self.len();
2466
2467    let begin = match range.start_bound() {
2468      Bound::Included(&n) => n,
2469      Bound::Excluded(&n) => n.checked_add(1).expect("out of range"),
2470      Bound::Unbounded => 0,
2471    };
2472
2473    let end = match range.end_bound() {
2474      Bound::Included(&n) => n.checked_add(1).expect("out of range"),
2475      Bound::Excluded(&n) => n,
2476      Bound::Unbounded => len,
2477    };
2478
2479    &self[begin..end]
2480  }
2481
2482  #[inline]
2483  fn try_segment(&self, range: impl RangeBounds<usize>) -> Result<Self, TrySegmentError> {
2484    check_segment(range, self.len()).map(|(begin, end)| &self[begin..end])
2485  }
2486
2487  #[inline]
2488  fn split_off(&mut self, at: usize) -> Self {
2489    let (left, right) = self.split_at(at);
2490    *self = left;
2491    right
2492  }
2493
2494  #[inline]
2495  fn split_off_checked(&mut self, at: usize) -> Option<Self> {
2496    let (left, right) = self.split_at_checked(at)?;
2497    *self = left;
2498    Some(right)
2499  }
2500
2501  #[inline]
2502  fn split_to(&mut self, at: usize) -> Self {
2503    let (left, right) = self.split_at(at);
2504    *self = right;
2505    left
2506  }
2507
2508  #[inline]
2509  fn split_to_checked(&mut self, at: usize) -> Option<Self> {
2510    let (left, right) = self.split_at_checked(at)?;
2511    *self = right;
2512    Some(left)
2513  }
2514
2515  #[inline]
2516  fn try_split_off(&mut self, at: usize) -> Result<Self, OutOfBounds> {
2517    self
2518      .split_at_checked(at)
2519      .ok_or_else(|| OutOfBounds::new(at, self.len()))
2520      .map(|(left, right)| {
2521        *self = left;
2522        right
2523      })
2524  }
2525
2526  #[inline]
2527  fn try_split_to(&mut self, at: usize) -> Result<Self, OutOfBounds> {
2528    self
2529      .split_at_checked(at)
2530      .ok_or_else(|| OutOfBounds::new(at, self.len()))
2531      .map(|(left, right)| {
2532        *self = right;
2533        left
2534      })
2535  }
2536
2537  #[inline]
2538  fn buffer(&self) -> &[u8] {
2539    self
2540  }
2541
2542  #[inline]
2543  fn buffer_from(&self, offset: usize) -> &[u8] {
2544    &self[offset..]
2545  }
2546
2547  #[inline]
2548  fn buffer_from_checked(&self, offset: usize) -> Option<&[u8]> {
2549    self.split_at_checked(offset).map(|(_, right)| right)
2550  }
2551}
2552
2553#[cfg(all(feature = "bytes_1", any(feature = "std", feature = "alloc")))]
2554const _: () = {
2555  use bytes_1::{Buf as _, Bytes};
2556
2557  macro_rules! read_fixed_specification {
2558    ($($ty:ident), +$(,)?) => {
2559      paste::paste! {
2560        $(
2561          fn [<read_ $ty _le>](&mut self) -> $ty {
2562            self.[<get_ $ty _le>]()
2563          }
2564
2565          fn [<read_ $ty _le_checked>](&mut self) -> Option<$ty> {
2566            self.[<try_get_ $ty _le>]().ok()
2567          }
2568
2569          fn [<try_read_ $ty _le>](&mut self) -> Result<$ty, TryReadError> {
2570            self.[<try_get_ $ty _le>]().map_err(Into::into)
2571          }
2572
2573          fn [<read_ $ty _be>](&mut self) -> $ty {
2574            self.[<get_ $ty>]()
2575          }
2576
2577          fn [<read_ $ty _be_checked>](&mut self) -> Option<$ty> {
2578            self.[<try_get_ $ty>]().ok()
2579          }
2580
2581          fn [<try_read_ $ty _be>](&mut self) -> Result<$ty, TryReadError> {
2582            self.[<try_get_ $ty>]().map_err(Into::into)
2583          }
2584
2585          fn [<read_ $ty _ne>](&mut self) -> $ty {
2586            self.[<get_ $ty _ne>]()
2587          }
2588
2589          fn [<read_ $ty _ne_checked>](&mut self) -> Option<$ty> {
2590            self.[<try_get_ $ty _ne>]().ok()
2591          }
2592
2593          fn [<try_read_ $ty _ne>](&mut self) -> Result<$ty, TryReadError> {
2594            self.[<try_get_ $ty _ne>]().map_err(Into::into)
2595          }
2596        )*
2597      }
2598    };
2599  }
2600
2601  #[cfg_attr(
2602    docsrs,
2603    doc(cfg(all(feature = "bytes_1", any(feature = "std", feature = "alloc"))))
2604  )]
2605  impl Chunk for Bytes {
2606    #[inline]
2607    fn remaining(&self) -> usize {
2608      self.len()
2609    }
2610
2611    #[inline]
2612    fn has_remaining(&self) -> bool {
2613      !self.is_empty()
2614    }
2615
2616    #[inline]
2617    fn buffer(&self) -> &[u8] {
2618      self.as_ref()
2619    }
2620
2621    #[inline]
2622    fn buffer_from(&self, offset: usize) -> &[u8] {
2623      &self.as_ref()[offset..]
2624    }
2625
2626    #[inline]
2627    fn buffer_from_checked(&self, offset: usize) -> Option<&[u8]> {
2628      self
2629        .as_ref()
2630        .split_at_checked(offset)
2631        .map(|(_, right)| right)
2632    }
2633
2634    #[inline]
2635    fn advance(&mut self, cnt: usize) {
2636      bytes_1::Buf::advance(self, cnt);
2637    }
2638
2639    #[inline]
2640    fn truncate(&mut self, len: usize) {
2641      Bytes::truncate(self, len);
2642    }
2643
2644    #[inline]
2645    fn segment(&self, range: impl RangeBounds<usize>) -> Self {
2646      Bytes::slice(self, range)
2647    }
2648
2649    #[inline]
2650    fn split_off(&mut self, at: usize) -> Self {
2651      Bytes::split_off(self, at)
2652    }
2653
2654    #[inline]
2655    fn split_to(&mut self, at: usize) -> Self {
2656      Bytes::split_to(self, at)
2657    }
2658
2659    #[inline]
2660    fn read_u8(&mut self) -> u8 {
2661      self.get_u8()
2662    }
2663
2664    #[inline]
2665    fn read_u8_checked(&mut self) -> Option<u8> {
2666      self.try_get_u8().ok()
2667    }
2668
2669    #[inline]
2670    fn try_read_u8(&mut self) -> Result<u8, TryReadError> {
2671      self.try_get_u8().map_err(Into::into)
2672    }
2673
2674    #[inline]
2675    fn read_i8(&mut self) -> i8 {
2676      self.get_i8()
2677    }
2678
2679    #[inline]
2680    fn read_i8_checked(&mut self) -> Option<i8> {
2681      self.try_get_i8().ok()
2682    }
2683
2684    #[inline]
2685    fn try_read_i8(&mut self) -> Result<i8, TryReadError> {
2686      self.try_get_i8().map_err(Into::into)
2687    }
2688
2689    #[cfg(all(feature = "bytes_1", any(feature = "std", feature = "alloc")))]
2690    fn to_bytes(&self) -> ::bytes_1::Bytes {
2691      self.clone()
2692    }
2693
2694    read_fixed_specification!(u16, u32, u64, u128, i16, i32, i64, i128, f32, f64);
2695  }
2696};
2697
2698#[inline]
2699fn check_segment<R: RangeBounds<usize>>(
2700  range: R,
2701  len: usize,
2702) -> Result<(usize, usize), TrySegmentError> {
2703  let begin = match range.start_bound() {
2704    Bound::Included(&n) => n,
2705    Bound::Excluded(&n) => match n.checked_add(1) {
2706      Some(val) => val,
2707      None => usize::MAX,
2708    },
2709    Bound::Unbounded => 0,
2710  };
2711
2712  let end = match range.end_bound() {
2713    Bound::Included(&n) => match n.checked_add(1) {
2714      Some(val) => val,
2715      None => usize::MAX,
2716    },
2717    Bound::Excluded(&n) => n,
2718    Bound::Unbounded => len,
2719  };
2720
2721  if begin > len || end > len || begin > end {
2722    return Err(TrySegmentError::new(begin, end, len));
2723  }
2724
2725  Ok((begin, end))
2726}
2727
2728#[inline]
2729fn read_array<B: Chunk + ?Sized, const N: usize>(buf: &mut B) -> [u8; N] {
2730  let output = peek_array::<B, N>(buf);
2731  buf.advance(N);
2732  output
2733}
2734
2735#[inline]
2736fn read_array_checked<B: Chunk + ?Sized, const N: usize>(buf: &mut B) -> Option<[u8; N]> {
2737  peek_array_checked::<B, N>(buf).inspect(|_| {
2738    buf.advance(N);
2739  })
2740}
2741
2742#[inline]
2743fn try_read_array<B: Chunk + ?Sized, const N: usize>(buf: &mut B) -> Result<[u8; N], TryReadError> {
2744  try_peek_array::<B, N>(buf)
2745    .inspect(|_| {
2746      buf.advance(N);
2747    })
2748    .map_err(Into::into)
2749}
2750
2751#[inline]
2752fn peek_array<B: Chunk + ?Sized, const N: usize>(buf: &B) -> [u8; N] {
2753  <[u8; N]>::try_from(&buf.buffer()[..N]).expect("Already checked there are enough bytes")
2754}
2755
2756#[inline]
2757fn peek_array_checked<B: Chunk + ?Sized, const N: usize>(buf: &B) -> Option<[u8; N]> {
2758  if N == 0 {
2759    return Some([0u8; N]);
2760  }
2761
2762  if buf.remaining() < N {
2763    None
2764  } else {
2765    Some(<[u8; N]>::try_from(&buf.buffer()[..N]).expect("Already checked there are enough bytes"))
2766  }
2767}
2768
2769#[inline]
2770fn try_peek_array<B: Chunk + ?Sized, const N: usize>(buf: &B) -> Result<[u8; N], TryPeekError> {
2771  if N == 0 {
2772    return Ok([0u8; N]);
2773  }
2774
2775  if buf.remaining() < N {
2776    Err(TryPeekError::new(must_non_zero(N), buf.remaining()))
2777  } else {
2778    Ok(<[u8; N]>::try_from(&buf.buffer()[..N]).expect("Already checked there are enough bytes"))
2779  }
2780}
2781
2782#[inline]
2783fn peek_array_at<B: Chunk + ?Sized, const N: usize>(buf: &B, offset: usize) -> [u8; N] {
2784  buf.buffer_from(offset)[..N].try_into().unwrap()
2785}
2786
2787#[inline]
2788fn peek_array_at_checked<B: Chunk + ?Sized, const N: usize>(
2789  buf: &B,
2790  offset: usize,
2791) -> Option<[u8; N]> {
2792  match buf.buffer_from_checked(offset) {
2793    Some(slice) if slice.len() >= N => Some(slice[..N].try_into().unwrap()),
2794    _ => None,
2795  }
2796}
2797
2798#[inline]
2799fn try_peek_array_at<B: Chunk + ?Sized, const N: usize>(
2800  buf: &B,
2801  offset: usize,
2802) -> Result<[u8; N], TryPeekAtError> {
2803  let buffer = buf.buffer();
2804  let buf_len = buffer.len();
2805
2806  match buf_len.checked_sub(offset) {
2807    None => Err(TryPeekAtError::out_of_bounds(offset, buf_len)),
2808    Some(_) if N == 0 => Ok([0u8; N]),
2809    Some(remaining) if remaining >= N => Ok(
2810      buffer[offset..offset + N]
2811        .try_into()
2812        .expect("Already checked there are enough bytes"),
2813    ),
2814    Some(remaining) => {
2815      let n = must_non_zero(N);
2816      let err = TryPeekAtError::insufficient_data_with_requested(remaining, offset, n);
2817      Err(err)
2818    }
2819  }
2820}
2821
2822#[inline]
2823fn check_out_of_bounds(method_name: &'static str, at: usize, remaining: usize) {
2824  assert!(
2825    at <= remaining,
2826    "{method_name} out of bounds: {at} <= {remaining}",
2827  );
2828}
2829
2830#[inline]
2831fn check_segment_range_bounds(begin: usize, end: usize, current_remaining: usize) {
2832  assert!(
2833    begin <= end,
2834    "range start must not be greater than end: {begin} <= {end}",
2835  );
2836  assert!(
2837    end <= current_remaining,
2838    "range end out of bounds: {end} <= {current_remaining}",
2839  );
2840}
2841
2842#[cfg(test)]
2843mod tests {
2844  use super::*;
2845
2846  struct Wrapper<'a>(&'a [u8]);
2847
2848  impl Chunk for Wrapper<'_> {
2849    fn remaining(&self) -> usize {
2850      self.0.len()
2851    }
2852
2853    fn buffer(&self) -> &[u8] {
2854      self.0
2855    }
2856
2857    fn advance(&mut self, cnt: usize) {
2858      if self.0.len() < cnt {
2859        panic_advance(&TryAdvanceError::new(must_non_zero(cnt), self.0.len()));
2860      }
2861
2862      self.0 = &self.0[cnt..];
2863    }
2864
2865    fn segment(&self, range: impl RangeBounds<usize>) -> Self
2866    where
2867      Self: Sized,
2868    {
2869      let len = self.0.len();
2870      let (begin, end) = check_segment(range, len).expect("out of range");
2871      Wrapper(&self.0[begin..end])
2872    }
2873
2874    fn truncate(&mut self, len: usize) {
2875      if len > self.0.len() {
2876        return;
2877      }
2878
2879      self.0 = &self.0[..len];
2880    }
2881
2882    fn split_off(&mut self, at: usize) -> Self
2883    where
2884      Self: Sized,
2885    {
2886      let (left, right) = self.0.split_at(at);
2887      self.0 = left;
2888      Wrapper(right)
2889    }
2890
2891    fn split_to(&mut self, at: usize) -> Self
2892    where
2893      Self: Sized,
2894    {
2895      let (left, right) = self.0.split_at(at);
2896      self.0 = right;
2897      Wrapper(left)
2898    }
2899  }
2900
2901  #[test]
2902  #[should_panic]
2903  fn test_advance_panic() {
2904    let buf = [0u8; 5];
2905    let mut slice = &buf[..];
2906    slice.advance(10);
2907  }
2908
2909  #[test]
2910  fn test_segment_edge() {
2911    let buf = [1, 2, 3, 4, 5];
2912    let slice = Wrapper(&buf[..]);
2913    let output = slice
2914      .try_segment((Bound::Excluded(1), Bound::Included(3)))
2915      .unwrap();
2916    assert_eq!(output.0, &[3, 4]);
2917
2918    assert!(slice
2919      .try_segment((Bound::Excluded(usize::MAX), Bound::Included(usize::MAX)))
2920      .is_err());
2921  }
2922
2923  #[test]
2924  #[should_panic]
2925  fn test_segment_panic() {
2926    let buf = [1, 2, 3, 4, 5];
2927    let slice = Wrapper(&buf[..]);
2928    let output = slice.segment((Bound::Excluded(1), Bound::Included(3)));
2929    assert_eq!(output.0, &[3, 4]);
2930
2931    slice.segment((Bound::Excluded(usize::MAX), Bound::Included(usize::MAX)));
2932  }
2933
2934  #[test]
2935  fn test_blanket_has_remaining() {
2936    let buf = [0u8; 5];
2937    let slice = Wrapper(&buf[..]);
2938    assert!(slice.has_remaining());
2939
2940    let empty = Wrapper(&[]);
2941    assert!(!empty.has_remaining());
2942  }
2943
2944  #[test]
2945  fn test_blanket_split_off() {
2946    let buf = [1, 2, 3, 4, 5];
2947    let mut slice = Wrapper(&buf[..]);
2948    let right = slice.split_off(2);
2949    assert_eq!(slice.0, &[1, 2]);
2950    assert_eq!(right.0, &[3, 4, 5]);
2951  }
2952
2953  #[test]
2954  fn test_blanket_split_off_checked() {
2955    let buf = [1, 2, 3, 4, 5];
2956    let mut slice = Wrapper(&buf[..]);
2957    let right = slice.split_off_checked(2).unwrap();
2958    assert_eq!(slice.0, &[1, 2]);
2959    assert_eq!(right.0, &[3, 4, 5]);
2960
2961    assert!(slice.split_off_checked(10).is_none());
2962  }
2963
2964  #[test]
2965  fn test_blanket_try_split_off() {
2966    let buf = [1, 2, 3, 4, 5];
2967    let mut slice = Wrapper(&buf[..]);
2968    let right = slice.try_split_off(2).unwrap();
2969    assert_eq!(slice.0, &[1, 2]);
2970    assert_eq!(right.0, &[3, 4, 5]);
2971
2972    assert!(slice.try_split_off(10).is_err());
2973  }
2974
2975  #[test]
2976  fn test_blanket_split_to() {
2977    let buf = [1, 2, 3, 4, 5];
2978    let mut slice = Wrapper(&buf[..]);
2979    let right = slice.split_to(2);
2980    assert_eq!(slice.0, &[3, 4, 5]);
2981    assert_eq!(right.0, &[1, 2]);
2982  }
2983
2984  #[test]
2985  fn test_blanket_split_to_checked() {
2986    let buf = [1, 2, 3, 4, 5];
2987    let mut slice = Wrapper(&buf[..]);
2988    let right = slice.split_to_checked(2).unwrap();
2989    assert_eq!(slice.0, &[3, 4, 5]);
2990    assert_eq!(right.0, &[1, 2]);
2991
2992    assert!(slice.split_to_checked(10).is_none());
2993  }
2994
2995  #[test]
2996  fn test_blanket_try_split_to() {
2997    let buf = [1, 2, 3, 4, 5];
2998    let mut slice = Wrapper(&buf[..]);
2999    let right = slice.try_split_to(2).unwrap();
3000    assert_eq!(slice.0, &[3, 4, 5]);
3001    assert_eq!(right.0, &[1, 2]);
3002
3003    assert!(slice.try_split_to(10).is_err());
3004  }
3005
3006  #[test]
3007  fn test_blanket_buffer_from() {
3008    let buf = [1, 2, 3, 4, 5];
3009    let slice = Wrapper(&buf[..]);
3010    assert_eq!(slice.buffer_from(2), &[3, 4, 5]);
3011  }
3012
3013  #[test]
3014  fn test_blanket_buffer_from_checked() {
3015    let buf = [1, 2, 3, 4, 5];
3016    let slice = Wrapper(&buf[..]);
3017    assert_eq!(slice.buffer_from_checked(2), Some(&[3, 4, 5][..]));
3018    assert_eq!(slice.buffer_from_checked(10), None);
3019  }
3020
3021  #[test]
3022  fn test_blanket_peek_array_0() {
3023    let buf = [1, 2, 3, 4, 5];
3024    let slice = Wrapper(&buf[..]);
3025    let arr: [u8; 0] = slice.peek_array();
3026    assert_eq!(arr, []);
3027
3028    let buf = [];
3029    let slice = Wrapper(&buf[..]);
3030    let arr: [u8; 0] = slice.peek_array();
3031    assert_eq!(arr, []);
3032  }
3033
3034  #[test]
3035  fn test_blanket_peek_checked_array_0() {
3036    let buf = [1, 2, 3, 4, 5];
3037    let slice = Wrapper(&buf[..]);
3038    let arr: Option<[u8; 0]> = slice.peek_array_checked();
3039    assert_eq!(arr, Some([]));
3040  }
3041
3042  #[test]
3043  fn test_blanket_try_peek_array_0() {
3044    let buf = [1, 2, 3, 4, 5];
3045    let slice = Wrapper(&buf[..]);
3046    let arr: Result<[u8; 0], TryPeekError> = slice.try_peek_array();
3047    assert_eq!(arr, Ok([]));
3048  }
3049
3050  #[test]
3051  fn test_blanket_peek_at_array_0() {
3052    let buf = [1, 2, 3, 4, 5];
3053    let slice = Wrapper(&buf[..]);
3054    let arr: [u8; 0] = slice.peek_array_at(2);
3055    assert_eq!(arr, []);
3056
3057    let buf = [1, 2, 3, 4, 5];
3058    let slice = Wrapper(&buf[..]);
3059    let arr: [u8; 0] = slice.peek_array_at(5);
3060    assert_eq!(arr, []);
3061
3062    let buf = [];
3063    let slice = Wrapper(&buf[..]);
3064    let arr: [u8; 0] = slice.peek_array_at(0);
3065    assert_eq!(arr, []);
3066  }
3067
3068  #[test]
3069  fn test_blanket_peek_at_checked_array_0() {
3070    let buf = [1, 2, 3, 4, 5];
3071    let slice = Wrapper(&buf[..]);
3072    let arr: Option<[u8; 0]> = slice.peek_array_at_checked(2);
3073    assert_eq!(arr, Some([]));
3074
3075    let buf = [1, 2, 3, 4, 5];
3076    let slice = Wrapper(&buf[..]);
3077    let arr: Option<[u8; 0]> = slice.peek_array_at_checked(5);
3078    assert_eq!(arr, Some([]));
3079
3080    let buf = [];
3081    let slice = Wrapper(&buf[..]);
3082    let arr: Option<[u8; 0]> = slice.peek_array_at_checked(0);
3083    assert_eq!(arr, Some([]));
3084
3085    let buf = [1, 2, 3, 4, 5];
3086    let slice = Wrapper(&buf[..]);
3087    let arr: Option<[u8; 0]> = slice.peek_array_at_checked(10);
3088    assert_eq!(arr, None);
3089  }
3090
3091  #[test]
3092  fn test_blanket_try_peek_at_array_0() {
3093    let buf = [1, 2, 3, 4, 5];
3094    let slice = Wrapper(&buf[..]);
3095    let arr: Result<[u8; 0], TryPeekAtError> = slice.try_peek_array_at(2);
3096    assert_eq!(arr, Ok([]));
3097
3098    let buf = [1, 2, 3, 4, 5];
3099    let slice = Wrapper(&buf[..]);
3100    let arr: Result<[u8; 0], TryPeekAtError> = slice.try_peek_array_at(5);
3101    assert_eq!(arr, Ok([]));
3102
3103    let buf = [];
3104    let slice = Wrapper(&buf[..]);
3105    let arr: Result<[u8; 0], TryPeekAtError> = slice.try_peek_array_at(0);
3106    assert_eq!(arr, Ok([]));
3107
3108    let buf = [1, 2, 3, 4, 5];
3109    let slice = Wrapper(&buf[..]);
3110    let arr: Result<[u8; 0], TryPeekAtError> = slice.try_peek_array_at(10);
3111    assert!(arr.is_err());
3112  }
3113
3114  #[test]
3115  #[cfg(feature = "bytes_1")]
3116  fn test_to_bytes() {
3117    let slice = Wrapper(&[1, 2, 3, 4, 5]);
3118    let bytes = slice.to_bytes();
3119    assert_eq!(bytes, bytes_1::Bytes::from(&[1, 2, 3, 4, 5][..]));
3120  }
3121}