capnp/
io.rs

1//! Custom I/O traits that roughly mirror `std::io::{Read, BufRead, Write}`.
2//! This extra layer of indirection enables support of no-std environments.
3
4use crate::{Error, ErrorKind, Result};
5
6/// A rough approximation of std::io::Read.
7pub trait Read {
8    /// Attempts to read some bytes into `buf` and returns the number of bytes read.
9    /// A return value of Ok(0) means that the end of the stream was reached.
10    ///
11    /// Unlike with std::io::Read, implementations are expected to handle EINTR
12    /// (i.e. std::io::ErrorKind::Interrupted) internally, by looping until either success
13    /// is achieved or some other error is hit.
14    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
15
16    fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
17        while !buf.is_empty() {
18            match self.read(buf)? {
19                0 => break,
20                n => {
21                    let tmp = buf;
22                    buf = &mut tmp[n..];
23                }
24            }
25        }
26        if !buf.is_empty() {
27            Err(Error::from_kind(ErrorKind::FailedToFillTheWholeBuffer))
28        } else {
29            Ok(())
30        }
31    }
32}
33
34/// A rough approximation of std::io::BufRead.
35pub trait BufRead: Read {
36    fn fill_buf(&mut self) -> Result<&[u8]>;
37    fn consume(&mut self, amt: usize);
38}
39
40/// A rough approximation of std::io::Write.
41pub trait Write {
42    fn write_all(&mut self, buf: &[u8]) -> Result<()>;
43}
44
45/// Blanket impls for when `std` is enabled.
46#[cfg(feature = "std")]
47mod std_impls {
48    use crate::io::{BufRead, Read, Write};
49    use crate::Result;
50
51    impl<R> Read for R
52    where
53        R: std::io::Read,
54    {
55        fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
56            loop {
57                match std::io::Read::read(self, buf) {
58                    Ok(n) => return Ok(n),
59                    Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {}
60                    Err(e) => return Err(e.into()),
61                }
62            }
63        }
64    }
65
66    impl<R> BufRead for R
67    where
68        R: std::io::BufRead,
69    {
70        fn fill_buf(&mut self) -> Result<&[u8]> {
71            Ok(std::io::BufRead::fill_buf(self)?)
72        }
73        fn consume(&mut self, amt: usize) {
74            std::io::BufRead::consume(self, amt)
75        }
76    }
77
78    impl<W> Write for W
79    where
80        W: std::io::Write,
81    {
82        fn write_all(&mut self, buf: &[u8]) -> Result<()> {
83            std::io::Write::write_all(self, buf)?;
84            Ok(())
85        }
86    }
87}
88
89/// Blanket impls for when `embedded-io` is enabled and `std` is not.
90#[cfg(all(feature = "embedded-io", not(feature = "std")))]
91mod embedded_io_impls {
92    use crate::io::{BufRead, Read, Write};
93    use crate::Result;
94    use embedded_io::Error;
95
96    impl<W: embedded_io::Write> Write for W {
97        fn write_all(&mut self, buf: &[u8]) -> Result<()> {
98            embedded_io::Write::write_all(self, buf)
99                .map_err(|e| crate::Error::from_kind(e.kind().into()))?;
100            Ok(())
101        }
102    }
103
104    impl<R: embedded_io::Read> Read for R {
105        fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
106            embedded_io::Read::read(self, buf).map_err(|e| crate::Error::from_kind(e.kind().into()))
107        }
108    }
109
110    impl<R: embedded_io::BufRead + embedded_io::Read> BufRead for R {
111        fn fill_buf(&mut self) -> Result<&[u8]> {
112            embedded_io::BufRead::fill_buf(self)
113                .map_err(|e| crate::Error::from_kind(e.kind().into()))
114        }
115
116        fn consume(&mut self, amt: usize) {
117            embedded_io::BufRead::consume(self, amt)
118        }
119    }
120}
121
122/// Fallback impls, for when neither `std` nor `embedded-io` is enabled.
123#[cfg(not(any(feature = "std", feature = "embedded-io")))]
124mod no_std_impls {
125    use crate::io::{BufRead, Read, Write};
126    use crate::{Error, ErrorKind, Result};
127
128    impl<'a> Write for &'a mut [u8] {
129        fn write_all(&mut self, buf: &[u8]) -> Result<()> {
130            if buf.len() > self.len() {
131                return Err(Error::from_kind(ErrorKind::BufferNotLargeEnough));
132            }
133            let amt = buf.len();
134            let (a, b) = core::mem::take(self).split_at_mut(amt);
135            a.copy_from_slice(buf);
136            *self = b;
137            Ok(())
138        }
139    }
140
141    #[cfg(feature = "alloc")]
142    impl Write for alloc::vec::Vec<u8> {
143        fn write_all(&mut self, buf: &[u8]) -> Result<()> {
144            self.extend_from_slice(buf);
145            Ok(())
146        }
147    }
148
149    impl<W: ?Sized> Write for &mut W
150    where
151        W: Write,
152    {
153        fn write_all(&mut self, buf: &[u8]) -> Result<()> {
154            (**self).write_all(buf)
155        }
156    }
157
158    impl<'a> Read for &'a [u8] {
159        fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
160            let amt = core::cmp::min(buf.len(), self.len());
161            let (a, b) = self.split_at(amt);
162
163            buf[..amt].copy_from_slice(a);
164            *self = b;
165            Ok(amt)
166        }
167    }
168
169    impl<R: ?Sized> Read for &mut R
170    where
171        R: Read,
172    {
173        fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
174            (**self).read(buf)
175        }
176    }
177
178    impl<'a> BufRead for &'a [u8] {
179        fn fill_buf(&mut self) -> Result<&[u8]> {
180            Ok(*self)
181        }
182        fn consume(&mut self, amt: usize) {
183            *self = &self[amt..]
184        }
185    }
186
187    impl<R: ?Sized> BufRead for &mut R
188    where
189        R: BufRead,
190    {
191        fn fill_buf(&mut self) -> Result<&[u8]> {
192            (**self).fill_buf()
193        }
194        fn consume(&mut self, amt: usize) {
195            (**self).consume(amt)
196        }
197    }
198}