1pub trait IoWrite {
6 type Error: core::error::Error;
8 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
10}
11
12#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
14pub enum WError {
15 BufferFull,
17}
18
19impl core::fmt::Display for WError {
20 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21 match self {
22 WError::BufferFull => write!(f, "Buffer is full"),
23 }
24 }
25}
26
27impl core::error::Error for WError {}
28
29pub struct SliceWriter<'a> {
31 buf: &'a mut [u8],
32 cursor: usize,
33}
34
35impl<'a> SliceWriter<'a> {
36 pub fn from_slice(buf: &'a mut [u8]) -> Self {
38 Self { buf, cursor: 0 }
39 }
40
41 fn len(&self) -> usize {
42 self.buf.len() - self.cursor
43 }
44}
45
46impl IoWrite for SliceWriter<'_> {
47 type Error = WError;
48
49 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
50 if self.len() >= buf.len() {
51 let to = &mut self.buf[self.cursor..self.cursor + buf.len()];
52 to.copy_from_slice(buf);
53 self.cursor += buf.len();
54 Ok(())
55 } else {
56 Err(WError::BufferFull)
57 }
58 }
59}
60
61#[cfg(not(any(test, feature = "std")))]
62impl IoWrite for &mut [u8] {
63 type Error = WError;
64
65 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
66 SliceWriter::from_slice(self).write(buf)
67 }
68}
69
70#[cfg(all(not(test), feature = "alloc", not(feature = "std")))]
71impl IoWrite for alloc::vec::Vec<u8> {
72 type Error = core::convert::Infallible;
73
74 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
75 VecRefWriter::new(self).write(buf)
76 }
77}
78
79#[cfg(feature = "alloc")]
80mod vec_writer {
81 use super::IoWrite;
82
83 pub struct VecRefWriter<'a> {
85 vec: &'a mut alloc::vec::Vec<u8>,
86 }
87
88 impl<'a> VecRefWriter<'a> {
89 pub fn new(vec: &'a mut alloc::vec::Vec<u8>) -> Self {
91 Self { vec }
92 }
93 }
94
95 impl IoWrite for VecRefWriter<'_> {
96 type Error = core::convert::Infallible;
97
98 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
99 self.vec.extend_from_slice(buf);
100 Ok(())
101 }
102 }
103
104 pub struct VecWriter {
106 vec: alloc::vec::Vec<u8>,
107 }
108
109 impl VecWriter {
110 pub fn new() -> Self {
112 Self {
113 vec: alloc::vec::Vec::new(),
114 }
115 }
116 pub fn into_vec(self) -> alloc::vec::Vec<u8> {
118 self.vec
119 }
120 }
121
122 impl Default for VecWriter {
123 fn default() -> Self {
124 Self::new()
125 }
126 }
127
128 impl IoWrite for VecWriter {
129 type Error = core::convert::Infallible;
130 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
131 self.vec.extend_from_slice(buf);
132 Ok(())
133 }
134 }
135}
136#[cfg(feature = "alloc")]
137pub use vec_writer::{VecRefWriter, VecWriter};
138
139#[cfg(any(test, feature = "std"))]
140impl<W> IoWrite for W
141where
142 W: std::io::Write,
143{
144 type Error = std::io::Error;
145
146 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
147 self.write_all(buf)
148 }
149}
150
151pub enum Reference<'de, 'a> {
153 Borrowed(&'de [u8]),
155 Copied(&'a [u8]),
157}
158
159impl Reference<'_, '_> {
160 pub fn as_bytes(&self) -> &[u8] {
162 match self {
163 Reference::Borrowed(b) => b,
164 Reference::Copied(b) => b,
165 }
166 }
167}
168
169pub trait IoRead<'de> {
171 type Error: core::error::Error + 'static;
173 fn read_slice<'a>(&'a mut self, len: usize) -> Result<Reference<'de, 'a>, Self::Error>;
175}
176
177pub struct SliceReader<'de> {
179 cursor: &'de [u8],
181}
182impl<'de> SliceReader<'de> {
183 pub fn new(buf: &'de [u8]) -> Self {
185 Self { cursor: buf }
186 }
187
188 pub fn rest(&self) -> &'de [u8] {
191 self.cursor
192 }
193}
194
195#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
197pub enum RError {
198 BufferEmpty,
200}
201
202impl core::fmt::Display for RError {
203 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
204 match self {
205 RError::BufferEmpty => write!(f, "Buffer is empty"),
206 }
207 }
208}
209
210impl core::error::Error for RError {}
211
212impl<'de> IoRead<'de> for SliceReader<'de> {
213 type Error = RError;
214
215 #[inline]
216 fn read_slice<'a>(&'a mut self, len: usize) -> Result<Reference<'de, 'a>, Self::Error> {
217 let (read, rest) = self
218 .cursor
219 .split_at_checked(len)
220 .ok_or(RError::BufferEmpty)?;
221 self.cursor = rest;
222 Ok(Reference::Borrowed(read))
223 }
224}
225
226#[cfg(feature = "std")]
227mod std_reader {
228 use super::IoRead;
229
230 pub struct StdReader<R> {
232 reader: R,
233 buf: std::vec::Vec<u8>,
234 }
235
236 impl<R> StdReader<R>
237 where
238 R: std::io::Read,
239 {
240 pub fn new(reader: R) -> Self {
242 Self {
243 reader,
244 buf: std::vec::Vec::new(),
245 }
246 }
247 }
248
249 impl<'de, R> IoRead<'de> for StdReader<R>
250 where
251 R: std::io::Read,
252 {
253 type Error = std::io::Error;
254
255 fn read_slice<'a>(
256 &'a mut self,
257 len: usize,
258 ) -> Result<super::Reference<'de, 'a>, Self::Error> {
259 if self.buf.len() < len {
260 self.buf.resize(len, 0);
261 };
262 self.reader.read_exact(&mut self.buf[..len])?;
263
264 Ok(super::Reference::Copied(&self.buf[..len]))
265 }
266 }
267}
268#[cfg(feature = "std")]
269pub use std_reader::StdReader;
270
271#[cfg(test)]
272mod tests {
273 use super::*;
274
275 #[test]
276 #[should_panic]
277 fn buffer_full() {
278 let buf: &mut [u8] = &mut [0u8];
279 let mut writer = SliceWriter::from_slice(buf);
280 writer.write(&[1, 2]).unwrap();
281 }
282}