std_shims/
io.rs

1#[cfg(not(feature = "std"))]
2mod shims {
3  use core::fmt::{self, Debug, Display, Formatter};
4  #[cfg(feature = "alloc")]
5  use extern_alloc::{boxed::Box, vec::Vec};
6  use crate::error::Error as CoreError;
7
8  /// The kind of error.
9  #[derive(Clone, Copy, PartialEq, Eq, Debug)]
10  pub enum ErrorKind {
11    UnexpectedEof,
12    Other,
13  }
14
15  /// An error.
16  #[derive(Debug)]
17  pub struct Error {
18    kind: ErrorKind,
19    #[cfg(feature = "alloc")]
20    error: Box<dyn Send + Sync + CoreError>,
21  }
22
23  impl Display for Error {
24    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25      <Self as Debug>::fmt(self, f)
26    }
27  }
28  impl CoreError for Error {}
29
30  #[cfg(not(feature = "alloc"))]
31  pub trait IntoBoxSendSyncError {}
32  #[cfg(not(feature = "alloc"))]
33  impl<I> IntoBoxSendSyncError for I {}
34  #[cfg(feature = "alloc")]
35  pub trait IntoBoxSendSyncError: Into<Box<dyn Send + Sync + CoreError>> {}
36  #[cfg(feature = "alloc")]
37  impl<I: Into<Box<dyn Send + Sync + CoreError>>> IntoBoxSendSyncError for I {}
38
39  impl Error {
40    /// Create a new error.
41    ///
42    /// The error object itself is silently dropped when `alloc` is not enabled.
43    #[allow(unused)]
44    pub fn new<E: 'static + IntoBoxSendSyncError>(kind: ErrorKind, error: E) -> Error {
45      #[cfg(not(feature = "alloc"))]
46      let res = Error { kind };
47      #[cfg(feature = "alloc")]
48      let res = Error { kind, error: error.into() };
49      res
50    }
51
52    /// Create a new error with `io::ErrorKind::Other` as its kind.
53    ///
54    /// The error object itself is silently dropped when `alloc` is not enabled.
55    #[allow(unused)]
56    pub fn other<E: 'static + IntoBoxSendSyncError>(error: E) -> Error {
57      #[cfg(not(feature = "alloc"))]
58      let res = Error { kind: ErrorKind::Other };
59      #[cfg(feature = "alloc")]
60      let res = Error { kind: ErrorKind::Other, error: error.into() };
61      res
62    }
63
64    /// The kind of error.
65    pub fn kind(&self) -> ErrorKind {
66      self.kind
67    }
68
69    /// Retrieve the inner error.
70    #[cfg(feature = "alloc")]
71    pub fn into_inner(self) -> Option<Box<dyn Send + Sync + CoreError>> {
72      Some(self.error)
73    }
74  }
75
76  pub type Result<T> = core::result::Result<T, Error>;
77
78  pub trait Read {
79    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
80
81    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
82      let read = self.read(buf)?;
83      if read != buf.len() {
84        Err(Error::new(ErrorKind::UnexpectedEof, "reader ran out of bytes"))?;
85      }
86      Ok(())
87    }
88  }
89
90  impl Read for &[u8] {
91    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
92      let read = buf.len().min(self.len());
93      buf[.. read].copy_from_slice(&self[.. read]);
94      *self = &self[read ..];
95      Ok(read)
96    }
97  }
98
99  impl<R: Read> Read for &mut R {
100    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
101      R::read(*self, buf)
102    }
103  }
104
105  pub trait BufRead: Read {
106    fn fill_buf(&mut self) -> Result<&[u8]>;
107    fn consume(&mut self, amt: usize);
108  }
109
110  impl BufRead for &[u8] {
111    fn fill_buf(&mut self) -> Result<&[u8]> {
112      Ok(*self)
113    }
114    fn consume(&mut self, amt: usize) {
115      *self = &self[amt ..];
116    }
117  }
118
119  pub trait Write {
120    fn write(&mut self, buf: &[u8]) -> Result<usize>;
121    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
122      if self.write(buf)? != buf.len() {
123        Err(Error::new(ErrorKind::UnexpectedEof, "writer ran out of bytes"))?;
124      }
125      Ok(())
126    }
127  }
128
129  #[cfg(feature = "alloc")]
130  impl Write for Vec<u8> {
131    fn write(&mut self, buf: &[u8]) -> Result<usize> {
132      self.extend(buf);
133      Ok(buf.len())
134    }
135  }
136}
137#[cfg(not(feature = "std"))]
138pub use shims::*;
139
140#[cfg(feature = "std")]
141pub use std::io::{ErrorKind, Error, Result, Read, BufRead, Write};