Skip to main content

lzf_rust/
io.rs

1// SPDX-License-Identifier: ISC
2#[cfg(not(feature = "std"))]
3use alloc::vec::Vec;
4
5use crate::{Error, Result};
6
7/// `no_std`-compatible read trait used by streaming interfaces.
8///
9/// This trait is intentionally close to `std::io::Read` so the same code can
10/// be shared across `std` and `no_std` builds.
11pub trait Read {
12    /// Reads bytes into `buf`, returning the number of bytes read.
13    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
14
15    /// Reads exactly `buf.len()` bytes into `buf`.
16    ///
17    /// Returns:
18    /// - `Ok(())` if the buffer was fully filled.
19    /// - `Err(Error::Eof)` if input ended early.
20    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
21        default_read_exact(self, buf)
22    }
23}
24
25/// `no_std`-compatible write trait used by streaming interfaces.
26///
27/// This trait mirrors the core behavior of `std::io::Write`.
28pub trait Write {
29    /// Writes bytes from `buf`, returning the number of bytes written.
30    fn write(&mut self, buf: &[u8]) -> Result<usize>;
31
32    /// Flushes buffered output.
33    fn flush(&mut self) -> Result<()>;
34
35    /// Writes all bytes from `buf`.
36    ///
37    /// Returns `Err(Error::WriteZero)` if the writer reports successful writes
38    /// of zero bytes before the full input is consumed.
39    fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
40        default_write_all(self, &mut buf)
41    }
42}
43
44#[inline]
45fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [u8]) -> Result<()> {
46    while !buf.is_empty() {
47        match this.read(buf) {
48            Ok(0) => break,
49            Ok(n) => buf = &mut buf[n..],
50            Err(Error::Interrupted) => {}
51            Err(e) => return Err(e),
52        }
53    }
54
55    if buf.is_empty() { Ok(()) } else { Err(Error::Eof) }
56}
57
58#[inline]
59fn default_write_all<W: Write + ?Sized>(this: &mut W, buf: &mut &[u8]) -> Result<()> {
60    while !buf.is_empty() {
61        match this.write(buf) {
62            Ok(0) => return Err(Error::WriteZero),
63            Ok(n) => *buf = &buf[n..],
64            Err(Error::Interrupted) => {}
65            Err(e) => return Err(e),
66        }
67    }
68    Ok(())
69}
70
71#[cfg(not(feature = "std"))]
72impl<R: Read + ?Sized> Read for &mut R {
73    #[inline(always)]
74    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
75        (**self).read(buf)
76    }
77
78    #[inline(always)]
79    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
80        (**self).read_exact(buf)
81    }
82}
83
84#[cfg(not(feature = "std"))]
85impl<W: Write + ?Sized> Write for &mut W {
86    #[inline(always)]
87    fn write(&mut self, buf: &[u8]) -> Result<usize> {
88        (**self).write(buf)
89    }
90
91    #[inline(always)]
92    fn flush(&mut self) -> Result<()> {
93        (**self).flush()
94    }
95}
96
97#[cfg(not(feature = "std"))]
98impl Read for &[u8] {
99    #[inline(always)]
100    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
101        let n = self.len().min(buf.len());
102        let (left, right) = self.split_at(n);
103        buf[..n].copy_from_slice(left);
104        *self = right;
105        Ok(n)
106    }
107}
108
109#[cfg(not(feature = "std"))]
110impl Write for &mut [u8] {
111    #[inline(always)]
112    fn write(&mut self, buf: &[u8]) -> Result<usize> {
113        if buf.is_empty() {
114            return Ok(0);
115        }
116        if self.is_empty() {
117            return Err(Error::WriteZero);
118        }
119
120        let n = buf.len().min(self.len());
121        self[..n].copy_from_slice(&buf[..n]);
122        let remaining = core::mem::take(self);
123        *self = &mut remaining[n..];
124        Ok(n)
125    }
126
127    #[inline(always)]
128    fn flush(&mut self) -> Result<()> {
129        Ok(())
130    }
131}
132
133#[cfg(not(feature = "std"))]
134impl Write for Vec<u8> {
135    #[inline(always)]
136    fn write(&mut self, buf: &[u8]) -> Result<usize> {
137        self.extend_from_slice(buf);
138        Ok(buf.len())
139    }
140
141    #[inline(always)]
142    fn flush(&mut self) -> Result<()> {
143        Ok(())
144    }
145}
146
147#[cfg(not(feature = "std"))]
148impl<R: Read + ?Sized> Read for alloc::boxed::Box<R> {
149    #[inline(always)]
150    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
151        (**self).read(buf)
152    }
153
154    #[inline(always)]
155    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
156        (**self).read_exact(buf)
157    }
158}
159
160#[cfg(not(feature = "std"))]
161impl<W: Write + ?Sized> Write for alloc::boxed::Box<W> {
162    #[inline(always)]
163    fn write(&mut self, buf: &[u8]) -> Result<usize> {
164        (**self).write(buf)
165    }
166
167    #[inline(always)]
168    fn flush(&mut self) -> Result<()> {
169        (**self).flush()
170    }
171}
172
173#[cfg(feature = "std")]
174impl<R: std::io::Read + ?Sized> Read for R {
175    #[inline]
176    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
177        std::io::Read::read(self, buf).map_err(Error::from)
178    }
179
180    #[inline]
181    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
182        std::io::Read::read_exact(self, buf).map_err(Error::from)
183    }
184}
185
186#[cfg(feature = "std")]
187impl<W: std::io::Write + ?Sized> Write for W {
188    #[inline]
189    fn write(&mut self, buf: &[u8]) -> Result<usize> {
190        std::io::Write::write(self, buf).map_err(Error::from)
191    }
192
193    #[inline]
194    fn flush(&mut self) -> Result<()> {
195        std::io::Write::flush(self).map_err(Error::from)
196    }
197
198    #[inline]
199    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
200        std::io::Write::write_all(self, buf).map_err(Error::from)
201    }
202}