bincode_next/de/
read.rs

1//! This module contains reader-based structs and traits.
2//!
3//! Because `std::io::Read` is only limited to `std` and not `core`, we provide 2 alternative readers.
4//!
5//! [`Reader`\] is a reader for sources that do not own their data. It is assumed that the reader's data is dropped after the `read` method is called. This reader is incapable of reading borrowed data, like `&str` and `&[u8]`.
6//!
7//! [`BorrowReader`\] is an extension of `Reader` that also allows returning borrowed data. A `BorrowReader` allows reading `&str` and `&[u8]`.
8//!
9//! Specifically the `Reader` trait is used by [`Decode`\] and the `BorrowReader` trait is used by [`BorrowDecode`\].
10//!
11//! [Decode]: ../trait.Decode.html
12//! [BorrowDecode]: ../trait.BorrowDecode.html
13
14use crate::error::DecodeError;
15
16/// A reader for owned data. See the module documentation for more information.
17pub trait Reader {
18    /// Fill the given `bytes` argument with values. Exactly the length of the given slice must be filled, or else an error must be returned.
19    /// Fill the given `bytes` argument with values. Exactly the length of the given slice must be filled, or else an error must be returned.
20    ///
21    /// # Errors
22    ///
23    /// Returns `DecodeError::UnexpectedEnd` if the reader does not have enough bytes.
24    fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError>;
25
26    /// If this reader wraps a buffer of any kind, this function lets callers access contents of
27    /// the buffer without passing data through a buffer first.
28    #[inline]
29    fn peek_read(&mut self, _: usize) -> Option<&[u8]> {
30        None
31    }
32
33    /// If an implementation of `peek_read` is provided, an implementation of this function
34    /// must be provided so that subsequent reads or peek-reads do not return the same bytes
35    #[inline]
36    fn consume(&mut self, _: usize) {}
37}
38
39impl<T> Reader for &mut T
40where
41    T: Reader,
42{
43    #[inline]
44    fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> {
45        (**self).read(bytes)
46    }
47
48    #[inline]
49    fn peek_read(&mut self, n: usize) -> Option<&[u8]> {
50        (**self).peek_read(n)
51    }
52
53    #[inline]
54    fn consume(&mut self, n: usize) {
55        (*self).consume(n);
56    }
57}
58
59/// A reader for borrowed data. Implementers of this must also implement the [`Reader`\] trait. See the module documentation for more information.
60pub trait BorrowReader<'storage>: Reader {
61    /// Read exactly `length` bytes and return a slice to this data. If not enough bytes could be read, an error should be returned.
62    ///
63    /// *note*: Exactly `length` bytes must be returned. If less bytes are returned, bincode may panic. If more bytes are returned, the excess bytes may be discarded.
64    ///
65    /// # Errors
66    ///
67    /// Returns `DecodeError::UnexpectedEnd` if the reader does not have enough bytes.
68    fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError>;
69}
70
71/// A reader type for `&[u8]` slices. Implements both [`Reader`\] and [`BorrowReader`\], and thus can be used for borrowed data.
72pub struct SliceReader<'storage> {
73    pub(crate) slice: &'storage [u8],
74}
75
76impl<'storage> SliceReader<'storage> {
77    /// Constructs a slice reader
78    #[must_use]
79    pub const fn new(bytes: &'storage [u8]) -> Self {
80        Self { slice: bytes }
81    }
82}
83
84impl<'storage> Reader for SliceReader<'storage> {
85    #[inline(always)]
86    fn read(&mut self, bytes: &mut [u8]) -> Result<(), DecodeError> {
87        if bytes.len() > self.slice.len() {
88            return Err(DecodeError::UnexpectedEnd {
89                additional: bytes.len() - self.slice.len(),
90            });
91        }
92        let (read_slice, remaining) = self.slice.split_at(bytes.len());
93        bytes.copy_from_slice(read_slice);
94        self.slice = remaining;
95
96        Ok(())
97    }
98
99    #[inline]
100    fn peek_read(&mut self, n: usize) -> Option<&'storage [u8]> {
101        self.slice.get(..n)
102    }
103
104    #[inline]
105    fn consume(&mut self, n: usize) {
106        self.slice = self.slice.get(n..).unwrap_or_default();
107    }
108}
109
110impl<'storage> BorrowReader<'storage> for SliceReader<'storage> {
111    #[inline(always)]
112    fn take_bytes(&mut self, length: usize) -> Result<&'storage [u8], DecodeError> {
113        if length > self.slice.len() {
114            return Err(DecodeError::UnexpectedEnd {
115                additional: length - self.slice.len(),
116            });
117        }
118        let (read_slice, remaining) = self.slice.split_at(length);
119        self.slice = remaining;
120        Ok(read_slice)
121    }
122}