embedded_io_adapters/
std.rs

1//! Adapters to/from `std::io` traits.
2
3use embedded_io::Error as _;
4
5/// Adapter from `std::io` traits.
6#[derive(Clone)]
7pub struct FromStd<T: ?Sized> {
8    inner: T,
9}
10
11impl<T> FromStd<T> {
12    /// Create a new adapter.
13    pub fn new(inner: T) -> Self {
14        Self { inner }
15    }
16
17    /// Consume the adapter, returning the inner object.
18    pub fn into_inner(self) -> T {
19        self.inner
20    }
21}
22
23impl<T: ?Sized> FromStd<T> {
24    /// Borrow the inner object.
25    pub fn inner(&self) -> &T {
26        &self.inner
27    }
28
29    /// Mutably borrow the inner object.
30    pub fn inner_mut(&mut self) -> &mut T {
31        &mut self.inner
32    }
33}
34
35impl<T: ?Sized> embedded_io::ErrorType for FromStd<T> {
36    type Error = std::io::Error;
37}
38
39impl<T: std::io::Read + ?Sized> embedded_io::Read for FromStd<T> {
40    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
41        self.inner.read(buf)
42    }
43
44    fn read_exact(
45        &mut self,
46        buf: &mut [u8],
47    ) -> Result<(), embedded_io::ReadExactError<Self::Error>> {
48        match self.inner.read_exact(buf) {
49            Ok(()) => Ok(()),
50            Err(error) if error.kind() == std::io::ErrorKind::UnexpectedEof => {
51                Err(embedded_io::ReadExactError::UnexpectedEof)
52            }
53            Err(error) => Err(error.into()),
54        }
55    }
56}
57
58impl<T: std::io::BufRead + ?Sized> embedded_io::BufRead for FromStd<T> {
59    fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
60        self.inner.fill_buf()
61    }
62
63    fn consume(&mut self, amt: usize) {
64        self.inner.consume(amt);
65    }
66}
67
68impl<T: std::io::Write + ?Sized> embedded_io::Write for FromStd<T> {
69    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
70        match self.inner.write(buf) {
71            Ok(0) if !buf.is_empty() => Err(std::io::ErrorKind::WriteZero.into()),
72            Ok(n) => Ok(n),
73            Err(e) => Err(e),
74        }
75    }
76
77    fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
78        self.inner.write_all(buf)
79    }
80
81    fn write_fmt(
82        &mut self,
83        fmt: core::fmt::Arguments<'_>,
84    ) -> Result<(), embedded_io::WriteFmtError<Self::Error>> {
85        Ok(self.inner.write_fmt(fmt)?)
86    }
87
88    fn flush(&mut self) -> Result<(), Self::Error> {
89        self.inner.flush()
90    }
91}
92
93impl<T: std::io::Seek + ?Sized> embedded_io::Seek for FromStd<T> {
94    fn seek(&mut self, pos: embedded_io::SeekFrom) -> Result<u64, Self::Error> {
95        self.inner.seek(pos.into())
96    }
97
98    fn rewind(&mut self) -> Result<(), Self::Error> {
99        self.inner.rewind()
100    }
101
102    fn stream_position(&mut self) -> Result<u64, Self::Error> {
103        self.inner.stream_position()
104    }
105
106    fn seek_relative(&mut self, offset: i64) -> Result<(), Self::Error> {
107        self.inner.seek_relative(offset)
108    }
109}
110
111/// Adapter to `std::io` traits.
112#[derive(Clone)]
113pub struct ToStd<T: ?Sized> {
114    inner: T,
115}
116
117impl<T> ToStd<T> {
118    /// Create a new adapter.
119    pub fn new(inner: T) -> Self {
120        Self { inner }
121    }
122
123    /// Consume the adapter, returning the inner object.
124    pub fn into_inner(self) -> T {
125        self.inner
126    }
127}
128
129impl<T: ?Sized> ToStd<T> {
130    /// Borrow the inner object.
131    pub fn inner(&self) -> &T {
132        &self.inner
133    }
134
135    /// Mutably borrow the inner object.
136    pub fn inner_mut(&mut self) -> &mut T {
137        &mut self.inner
138    }
139}
140
141impl<T: embedded_io::Read + ?Sized> std::io::Read for ToStd<T> {
142    fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
143        self.inner.read(buf).map_err(to_std_error)
144    }
145
146    fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
147        match self.inner.read_exact(buf) {
148            Ok(()) => Ok(()),
149            Err(e @ embedded_io::ReadExactError::UnexpectedEof) => Err(std::io::Error::new(
150                std::io::ErrorKind::UnexpectedEof,
151                format!("{e:?}"),
152            )),
153            Err(embedded_io::ReadExactError::Other(e)) => Err(to_std_error(e)),
154        }
155    }
156}
157
158impl<T: embedded_io::Write + ?Sized> std::io::Write for ToStd<T> {
159    fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
160        match self.inner.write(buf) {
161            Ok(n) => Ok(n),
162            Err(e) if e.kind() == embedded_io::ErrorKind::WriteZero => Ok(0),
163            Err(e) => Err(to_std_error(e)),
164        }
165    }
166
167    fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
168        self.inner.write_all(buf).map_err(to_std_error)
169    }
170
171    fn write_fmt(&mut self, fmt: core::fmt::Arguments<'_>) -> Result<(), std::io::Error> {
172        match self.inner.write_fmt(fmt) {
173            Ok(()) => Ok(()),
174            Err(e @ embedded_io::WriteFmtError::FmtError) => {
175                Err(std::io::Error::other(format!("{e:?}")))
176            }
177            Err(embedded_io::WriteFmtError::Other(e)) => Err(to_std_error(e)),
178        }
179    }
180
181    fn flush(&mut self) -> Result<(), std::io::Error> {
182        self.inner.flush().map_err(to_std_error)
183    }
184}
185
186impl<T: embedded_io::Seek + ?Sized> std::io::Seek for ToStd<T> {
187    fn seek(&mut self, pos: std::io::SeekFrom) -> Result<u64, std::io::Error> {
188        self.inner.seek(pos.into()).map_err(to_std_error)
189    }
190
191    fn rewind(&mut self) -> Result<(), std::io::Error> {
192        self.inner.rewind().map_err(to_std_error)
193    }
194
195    fn stream_position(&mut self) -> Result<u64, std::io::Error> {
196        self.inner.stream_position().map_err(to_std_error)
197    }
198
199    fn seek_relative(&mut self, offset: i64) -> std::io::Result<()> {
200        self.inner.seek_relative(offset).map_err(to_std_error)
201    }
202}
203
204/// Convert a embedded-io error to a [`std::io::Error`]
205pub fn to_std_error<T: embedded_io::Error>(err: T) -> std::io::Error {
206    std::io::Error::new(err.kind().into(), format!("{err:?}"))
207}