core_json/
io.rs

1use core::{marker::PhantomData, fmt::Debug};
2
3/// A no-`std` `io::Read` alternative.
4///
5/// While plenty of crates define their own, we avoid external dependencies by once again defining
6/// our own. For those who wish to use [`embedded-io`](https://docs.rs/embedded-io), please see
7/// [`core-json-embedded-io`](https://docs.rs/core-json-embedded-io).
8pub trait Read<'read>: Sized + Debug {
9  /// The type for errors when interacting with this reader.
10  type Error: Sized + Copy + Debug;
11
12  /// Read a single byte from the reader.
13  fn read_byte(&mut self) -> Result<u8, Self::Error>;
14
15  /// Read into a slice from the reader.
16  fn read_exact(&mut self, slice: &mut [u8]) -> Result<(), Self::Error>;
17}
18
19/// A wrapper for an `impl Read` with a one-byte buffer, enabling peeking.
20///
21/// This will always read at least one byte from the underlying reader.
22pub(crate) struct PeekableRead<'read, R: Read<'read>> {
23  buffer: u8,
24  reader: R,
25  _read: PhantomData<&'read ()>,
26}
27
28impl<'read, R: Read<'read>> PeekableRead<'read, R> {
29  pub(crate) fn try_from(mut reader: R) -> Result<Self, R::Error> {
30    Ok(Self { buffer: reader.read_byte()?, reader, _read: PhantomData })
31  }
32}
33
34impl<'read, R: Read<'read>> PeekableRead<'read, R> {
35  #[must_use]
36  #[inline(always)]
37  pub(crate) fn peek(&self) -> u8 {
38    self.buffer
39  }
40
41  #[inline(always)]
42  pub(crate) fn read_byte(&mut self) -> Result<u8, R::Error> {
43    let res = self.buffer;
44    self.buffer = self.reader.read_byte()?;
45    Ok(res)
46  }
47
48  /// Read into a slice with a length which is non-zero.
49  ///
50  /// This will panic if the destination slice is empty, which is safe due to how we call it
51  /// (entirely internal to this library).
52  #[inline(always)]
53  pub(crate) fn read_exact_into_non_empty_slice(
54    &mut self,
55    slice: &mut [u8],
56  ) -> Result<(), R::Error> {
57    slice[0] = self.buffer;
58    self.reader.read_exact(&mut slice[1 ..])?;
59    // Since we've consumed the buffer, update it with the byte after the read slice
60    self.buffer = self.reader.read_byte()?;
61    Ok(())
62  }
63}
64
65/// An error when working with `&[u8]`.
66#[derive(Clone, Copy, Debug)]
67#[allow(dead_code)]
68pub enum SliceError {
69  /// The slice was short by `{0}` bytes.
70  Short(usize),
71}
72
73impl<'read> Read<'read> for &'read [u8] {
74  type Error = SliceError;
75
76  #[inline(always)]
77  fn read_byte(&mut self) -> Result<u8, Self::Error> {
78    let res = *self.first().ok_or(SliceError::Short(1))?;
79    *self = &self[1 ..];
80    Ok(res)
81  }
82
83  #[inline(always)]
84  fn read_exact(&mut self, slice: &mut [u8]) -> Result<(), Self::Error> {
85    if self.len() < slice.len() {
86      Err(SliceError::Short(slice.len() - self.len()))?;
87    }
88    slice.copy_from_slice(&self[.. slice.len()]);
89    *self = &self[slice.len() ..];
90    Ok(())
91  }
92}
93
94impl<'read, R: Read<'read>> Read<'read> for &mut R {
95  type Error = R::Error;
96
97  #[inline(always)]
98  fn read_byte(&mut self) -> Result<u8, Self::Error> {
99    R::read_byte(self)
100  }
101
102  #[inline(always)]
103  fn read_exact(&mut self, slice: &mut [u8]) -> Result<(), Self::Error> {
104    R::read_exact(self, slice)
105  }
106}