aead_io/
rw.rs

1/// Emulates [`std::io::Write`](std::io::Write) with a simplified interface for `no_std`
2/// environments.
3pub trait Write {
4    type Error;
5    /// Write a buffer into this writer, returning how many bytes were written.
6    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error>;
7    /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination.
8    fn flush(&mut self) -> Result<(), Self::Error>;
9    /// Attempts to write an entire buffer into this writer.
10    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
11}
12
13#[cfg(feature = "std")]
14impl<T> Write for T
15where
16    T: std::io::Write,
17{
18    type Error = std::io::Error;
19    #[inline]
20    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
21        std::io::Write::write(self, buf)
22    }
23    #[inline]
24    fn flush(&mut self) -> Result<(), Self::Error> {
25        std::io::Write::flush(self)
26    }
27    #[inline]
28    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
29        std::io::Write::write_all(self, buf)
30    }
31}
32
33/// Emulates [`std::io::Read`](std::io::Read) with a simplified interface for `no_std`
34/// environments.
35pub trait Read {
36    type Error;
37    /// Pull some bytes from this source into the specified buffer, returning how many bytes were read.
38    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
39    /// Read the exact number of bytes required to fill `buf`.
40    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error>;
41}
42
43#[cfg(feature = "std")]
44impl<T> Read for T
45where
46    T: std::io::Read,
47{
48    type Error = std::io::Error;
49    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
50        self.read(buf)
51    }
52    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
53        self.read_exact(buf)
54    }
55}
56
57/// A simple Error for implementations on byte slices in a `no_std` environment
58#[cfg(not(feature = "std"))]
59#[derive(Debug, Clone, Copy, Eq, PartialEq)]
60pub enum IoError {
61    /// Reached the end of the buffer when reading
62    UnexpectedEof,
63    /// Reached the end of the buffer when writing
64    WriteZero,
65}
66
67#[cfg(not(feature = "std"))]
68impl core::fmt::Display for IoError {
69    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
70        match self {
71            IoError::UnexpectedEof => f.write_str("Failed to fill whole buffer"),
72            IoError::WriteZero => f.write_str("Failed to write whole buffer"),
73        }
74    }
75}
76
77#[cfg(not(feature = "std"))]
78impl Read for &[u8] {
79    type Error = IoError;
80    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
81        let amt = core::cmp::min(buf.len(), self.len());
82        let (a, b) = self.split_at(amt);
83
84        // First check if the amount of bytes we want to read is small:
85        // `copy_from_slice` will generally expand to a call to `memcpy`, and
86        // for a single byte the overhead is significant.
87        if amt == 1 {
88            buf[0] = a[0];
89        } else {
90            buf[..amt].copy_from_slice(a);
91        }
92
93        *self = b;
94        Ok(amt)
95    }
96    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
97        if buf.len() > self.len() {
98            return Err(IoError::UnexpectedEof);
99        }
100        let (a, b) = self.split_at(buf.len());
101
102        // First check if the amount of bytes we want to read is small:
103        // `copy_from_slice` will generally expand to a call to `memcpy`, and
104        // for a single byte the overhead is significant.
105        if buf.len() == 1 {
106            buf[0] = a[0];
107        } else {
108            buf.copy_from_slice(a);
109        }
110
111        *self = b;
112        Ok(())
113    }
114}
115
116#[cfg(not(feature = "std"))]
117impl Write for &mut [u8] {
118    type Error = IoError;
119    #[inline]
120    fn write(&mut self, data: &[u8]) -> Result<usize, Self::Error> {
121        let amt = core::cmp::min(data.len(), self.len());
122        let (a, b) = core::mem::replace(self, &mut []).split_at_mut(amt);
123        a.copy_from_slice(&data[..amt]);
124        *self = b;
125        Ok(amt)
126    }
127    #[inline]
128    fn flush(&mut self) -> Result<(), Self::Error> {
129        Ok(())
130    }
131    #[inline]
132    fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error> {
133        if self.write(data)? == data.len() {
134            Ok(())
135        } else {
136            Err(IoError::WriteZero)
137        }
138    }
139}
140
141#[cfg(all(not(feature = "std"), feature = "alloc"))]
142impl Write for alloc::vec::Vec<u8> {
143    type Error = core::convert::Infallible;
144    #[inline]
145    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
146        self.extend_from_slice(buf);
147        Ok(buf.len())
148    }
149    #[inline]
150    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
151        self.extend_from_slice(buf);
152        Ok(())
153    }
154    #[inline]
155    fn flush(&mut self) -> Result<(), Self::Error> {
156        Ok(())
157    }
158}
159
160#[cfg(not(feature = "std"))]
161impl<R: Read + ?Sized> Read for &mut R {
162    type Error = R::Error;
163    #[inline]
164    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
165        (**self).read(buf)
166    }
167    #[inline]
168    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
169        (**self).read_exact(buf)
170    }
171}
172#[cfg(not(feature = "std"))]
173impl<W: Write + ?Sized> Write for &mut W {
174    type Error = W::Error;
175    #[inline]
176    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
177        (**self).write(buf)
178    }
179    #[inline]
180    fn flush(&mut self) -> Result<(), Self::Error> {
181        (**self).flush()
182    }
183    #[inline]
184    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
185        (**self).write_all(buf)
186    }
187}
188#[cfg(all(not(feature = "std"), feature = "alloc"))]
189impl<R: Read + ?Sized> Read for alloc::boxed::Box<R> {
190    type Error = R::Error;
191    #[inline]
192    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
193        (**self).read(buf)
194    }
195    #[inline]
196    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
197        (**self).read_exact(buf)
198    }
199}
200#[cfg(all(not(feature = "std"), feature = "alloc"))]
201impl<W: Write + ?Sized> Write for alloc::boxed::Box<W> {
202    type Error = W::Error;
203    #[inline]
204    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
205        (**self).write(buf)
206    }
207    #[inline]
208    fn flush(&mut self) -> Result<(), Self::Error> {
209        (**self).flush()
210    }
211    #[inline]
212    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
213        (**self).write_all(buf)
214    }
215}