1#![cfg_attr(not(feature = "std"), no_std)]
12
13#![warn(missing_docs)]
15
16#![allow(clippy::needless_question_mark)] #![allow(clippy::manual_range_contains)] #[cfg(feature = "alloc")]
21extern crate alloc;
22
23mod error;
24mod macros;
25#[cfg(feature = "std")]
26mod bridge;
27
28#[cfg(feature = "std")]
29pub use bridge::{FromStd, ToStd};
30
31#[cfg(all(not(feature = "std"), feature = "alloc"))]
32use alloc::vec::Vec;
33use core::cmp;
34
35#[rustfmt::skip] pub use self::error::{Error, ErrorKind};
37
38pub type Result<T> = core::result::Result<T, Error>;
40
41pub trait Read {
43 fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
45
46 #[inline]
48 fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
49 while !buf.is_empty() {
50 match self.read(buf) {
51 Ok(0) => return Err(ErrorKind::UnexpectedEof.into()),
52 Ok(len) => buf = &mut buf[len..],
53 Err(e) if e.kind() == ErrorKind::Interrupted => {}
54 Err(e) => return Err(e),
55 }
56 }
57 Ok(())
58 }
59
60 #[inline]
62 fn take(&mut self, limit: u64) -> Take<'_, Self> { Take { reader: self, remaining: limit } }
63
64 #[doc(alias = "read_to_end")]
71 #[cfg(feature = "alloc")]
72 #[inline]
73 fn read_to_limit(&mut self, buf: &mut Vec<u8>, limit: u64) -> Result<usize> {
74 self.take(limit).read_to_end(buf)
75 }
76}
77
78pub trait BufRead: Read {
80 fn fill_buf(&mut self) -> Result<&[u8]>;
82
83 fn consume(&mut self, amount: usize);
89}
90
91pub struct Take<'a, R: Read + ?Sized> {
95 reader: &'a mut R,
96 remaining: u64,
97}
98
99impl<'a, R: Read + ?Sized> Take<'a, R> {
100 #[cfg(feature = "alloc")]
102 #[inline]
103 pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
104 let mut read: usize = 0;
105 let mut chunk = [0u8; 64];
106 loop {
107 match self.read(&mut chunk) {
108 Ok(0) => break,
109 Ok(n) => {
110 buf.extend_from_slice(&chunk[0..n]);
111 read += n;
112 }
113 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
114 Err(e) => return Err(e),
115 };
116 }
117 Ok(read)
118 }
119}
120
121impl<'a, R: Read + ?Sized> Read for Take<'a, R> {
122 #[inline]
123 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
124 let len = cmp::min(buf.len(), self.remaining.try_into().unwrap_or(buf.len()));
125 let read = self.reader.read(&mut buf[..len])?;
126 self.remaining -= read.try_into().unwrap_or(self.remaining);
127 Ok(read)
128 }
129}
130
131impl<'a, R: BufRead + ?Sized> BufRead for Take<'a, R> {
133 #[inline]
134 fn fill_buf(&mut self) -> Result<&[u8]> {
135 if self.remaining == 0 {
137 return Ok(&[]);
138 }
139
140 let buf = self.reader.fill_buf()?;
141 let cap = cmp::min(buf.len() as u64, self.remaining) as usize;
144 Ok(&buf[..cap])
145 }
146
147 #[inline]
148 fn consume(&mut self, amount: usize) {
149 assert!(amount as u64 <= self.remaining);
150 self.remaining -= amount as u64;
151 self.reader.consume(amount);
152 }
153}
154
155impl Read for &[u8] {
156 #[inline]
157 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
158 let cnt = cmp::min(self.len(), buf.len());
159 buf[..cnt].copy_from_slice(&self[..cnt]);
160 *self = &self[cnt..];
161 Ok(cnt)
162 }
163}
164
165impl BufRead for &[u8] {
166 #[inline]
167 fn fill_buf(&mut self) -> Result<&[u8]> { Ok(self) }
168
169 #[inline]
171 fn consume(&mut self, amount: usize) { *self = &self[amount..] }
172}
173
174pub struct Cursor<T> {
176 inner: T,
177 pos: u64,
178}
179
180impl<T: AsRef<[u8]>> Cursor<T> {
181 #[inline]
183 pub fn new(inner: T) -> Self { Cursor { inner, pos: 0 } }
184
185 #[inline]
187 pub fn position(&self) -> u64 { self.pos }
188
189 #[inline]
196 pub fn set_position(&mut self, position: u64) {
197 self.pos = position;
198 }
199
200 #[inline]
204 pub fn into_inner(self) -> T { self.inner }
205
206 #[inline]
210 pub fn inner(&self) -> &T { &self.inner }
211}
212
213impl<T: AsRef<[u8]>> Read for Cursor<T> {
214 #[inline]
215 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
216 let inner: &[u8] = self.inner.as_ref();
217 let start_pos = self.pos.try_into().unwrap_or(inner.len());
218 let read = core::cmp::min(inner.len().saturating_sub(start_pos), buf.len());
219 buf[..read].copy_from_slice(&inner[start_pos..start_pos + read]);
220 self.pos =
221 self.pos.saturating_add(read.try_into().unwrap_or(u64::MAX ));
222 Ok(read)
223 }
224}
225
226impl<T: AsRef<[u8]>> BufRead for Cursor<T> {
227 #[inline]
228 fn fill_buf(&mut self) -> Result<&[u8]> {
229 let inner: &[u8] = self.inner.as_ref();
230 Ok(&inner[self.pos as usize..])
231 }
232
233 #[inline]
234 fn consume(&mut self, amount: usize) {
235 assert!(amount <= self.inner.as_ref().len());
236 self.pos += amount as u64;
237 }
238}
239
240pub trait Write {
242 fn write(&mut self, buf: &[u8]) -> Result<usize>;
244
245 fn flush(&mut self) -> Result<()>;
248
249 #[inline]
251 fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
252 while !buf.is_empty() {
253 match self.write(buf) {
254 Ok(0) => return Err(ErrorKind::UnexpectedEof.into()),
255 Ok(len) => buf = &buf[len..],
256 Err(e) if e.kind() == ErrorKind::Interrupted => {}
257 Err(e) => return Err(e),
258 }
259 }
260 Ok(())
261 }
262}
263
264#[cfg(feature = "alloc")]
265impl Write for alloc::vec::Vec<u8> {
266 #[inline]
267 fn write(&mut self, buf: &[u8]) -> Result<usize> {
268 self.extend_from_slice(buf);
269 Ok(buf.len())
270 }
271
272 #[inline]
273 fn flush(&mut self) -> Result<()> { Ok(()) }
274}
275
276impl Write for &'_ mut [u8] {
277 #[inline]
278 fn write(&mut self, buf: &[u8]) -> Result<usize> {
279 let cnt = core::cmp::min(self.len(), buf.len());
280 self[..cnt].copy_from_slice(&buf[..cnt]);
281 *self = &mut core::mem::take(self)[cnt..];
282 Ok(cnt)
283 }
284
285 #[inline]
286 fn flush(&mut self) -> Result<()> { Ok(()) }
287}
288
289pub struct Sink;
293
294impl Write for Sink {
295 #[inline]
296 fn write(&mut self, buf: &[u8]) -> Result<usize> { Ok(buf.len()) }
297
298 #[inline]
299 fn write_all(&mut self, _: &[u8]) -> Result<()> { Ok(()) }
300
301 #[inline]
302 fn flush(&mut self) -> Result<()> { Ok(()) }
303}
304
305#[inline]
307pub fn sink() -> Sink { Sink }
308
309#[cfg(feature = "std")]
313#[inline]
314pub const fn from_std<T>(std_io: T) -> FromStd<T> {
315 FromStd::new(std_io)
316}
317
318#[cfg(feature = "std")]
322#[inline]
323pub fn from_std_mut<T>(std_io: &mut T) -> &mut FromStd<T> {
324 FromStd::new_mut(std_io)
325}
326
327#[cfg(test)]
328mod tests {
329 use super::*;
330
331 #[cfg(all(not(feature = "std"), feature = "alloc"))]
332 use alloc::{string::ToString, vec};
333
334 #[test]
335 fn buf_read_fill_and_consume_slice() {
336 let data = [0_u8, 1, 2];
337
338 let mut slice = &data[..];
339
340 let fill = BufRead::fill_buf(&mut slice).unwrap();
341 assert_eq!(fill.len(), 3);
342 assert_eq!(fill, &[0_u8, 1, 2]);
343 slice.consume(2);
344
345 let fill = BufRead::fill_buf(&mut slice).unwrap();
346 assert_eq!(fill.len(), 1);
347 assert_eq!(fill, &[2_u8]);
348 slice.consume(1);
349
350 let fill = BufRead::fill_buf(&mut slice).unwrap();
352 assert_eq!(fill.len(), 0);
353 assert_eq!(fill, &[]);
354 }
355
356 #[test]
357 #[cfg(feature = "alloc")]
358 fn read_to_limit_greater_than_total_length() {
359 let s = "16-byte-string!!".to_string();
360 let mut reader = Cursor::new(&s);
361 let mut buf = vec![];
362
363 let read = reader.read_to_limit(&mut buf, 32).expect("failed to read to limit");
365 assert_eq!(read, s.len());
366 assert_eq!(&buf, s.as_bytes())
367 }
368
369 #[test]
370 #[cfg(feature = "alloc")]
371 fn read_to_limit_less_than_total_length() {
372 let s = "16-byte-string!!".to_string();
373 let mut reader = Cursor::new(&s);
374 let mut buf = vec![];
375
376 let read = reader.read_to_limit(&mut buf, 2).expect("failed to read to limit");
377 assert_eq!(read, 2);
378 assert_eq!(&buf, "16".as_bytes())
379 }
380}