1#![cfg_attr(not(feature = "std"), no_std)]
12#![cfg_attr(docsrs, feature(doc_auto_cfg))]
14#![warn(missing_docs)]
16#![doc(test(attr(warn(unused))))]
17#![allow(clippy::needless_question_mark)] #![allow(clippy::manual_range_contains)] #![allow(clippy::needless_borrows_for_generic_args)] #[cfg(feature = "alloc")]
23extern crate alloc;
24
25#[cfg(feature = "std")]
26mod bridge;
27mod error;
28mod macros;
29
30#[cfg(all(not(feature = "std"), feature = "alloc"))]
31use alloc::vec::Vec;
32use core::cmp;
33
34#[cfg(feature = "std")]
35pub use bridge::{FromStd, ToStd};
36
37#[rustfmt::skip] pub use self::error::{Error, ErrorKind};
39
40pub type Result<T> = core::result::Result<T, Error>;
42
43pub trait Read {
45 fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
47
48 #[inline]
50 fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
51 while !buf.is_empty() {
52 match self.read(buf) {
53 Ok(0) => return Err(ErrorKind::UnexpectedEof.into()),
54 Ok(len) => buf = &mut buf[len..],
55 Err(e) if e.kind() == ErrorKind::Interrupted => {}
56 Err(e) => return Err(e),
57 }
58 }
59 Ok(())
60 }
61
62 #[inline]
64 fn take(&mut self, limit: u64) -> Take<Self> { Take { reader: self, remaining: limit } }
65
66 #[doc(alias = "read_to_end")]
73 #[cfg(feature = "alloc")]
74 #[inline]
75 fn read_to_limit(&mut self, buf: &mut Vec<u8>, limit: u64) -> Result<usize> {
76 self.take(limit).read_to_end(buf)
77 }
78}
79
80pub trait BufRead: Read {
82 fn fill_buf(&mut self) -> Result<&[u8]>;
84
85 fn consume(&mut self, amount: usize);
91}
92
93pub struct Take<'a, R: Read + ?Sized> {
97 reader: &'a mut R,
98 remaining: u64,
99}
100
101impl<'a, R: Read + ?Sized> Take<'a, R> {
102 #[cfg(feature = "alloc")]
104 #[inline]
105 pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
106 let mut read: usize = 0;
107 let mut chunk = [0u8; 64];
108 loop {
109 match self.read(&mut chunk) {
110 Ok(0) => break,
111 Ok(n) => {
112 buf.extend_from_slice(&chunk[0..n]);
113 read += n;
114 }
115 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
116 Err(e) => return Err(e),
117 };
118 }
119 Ok(read)
120 }
121}
122
123impl<'a, R: Read + ?Sized> Read for Take<'a, R> {
124 #[inline]
125 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
126 let len = cmp::min(buf.len(), self.remaining.try_into().unwrap_or(buf.len()));
127 let read = self.reader.read(&mut buf[..len])?;
128 self.remaining -= read.try_into().unwrap_or(self.remaining);
129 Ok(read)
130 }
131}
132
133impl<'a, R: BufRead + ?Sized> BufRead for Take<'a, R> {
135 #[inline]
136 fn fill_buf(&mut self) -> Result<&[u8]> {
137 if self.remaining == 0 {
139 return Ok(&[]);
140 }
141
142 let buf = self.reader.fill_buf()?;
143 let cap = cmp::min(buf.len() as u64, self.remaining) as usize;
146 Ok(&buf[..cap])
147 }
148
149 #[inline]
150 fn consume(&mut self, amount: usize) {
151 assert!(amount as u64 <= self.remaining);
152 self.remaining -= amount as u64;
153 self.reader.consume(amount);
154 }
155}
156
157impl<T: Read> Read for &'_ mut T {
158 #[inline]
159 fn read(&mut self, buf: &mut [u8]) -> Result<usize> { (**self).read(buf) }
160
161 #[inline]
162 fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { (**self).read_exact(buf) }
163}
164
165impl<T: BufRead> BufRead for &'_ mut T {
166 #[inline]
167 fn fill_buf(&mut self) -> Result<&[u8]> { (**self).fill_buf() }
168
169 #[inline]
170 fn consume(&mut self, amount: usize) { (**self).consume(amount) }
171}
172
173impl Read for &[u8] {
174 #[inline]
175 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
176 let cnt = cmp::min(self.len(), buf.len());
177 buf[..cnt].copy_from_slice(&self[..cnt]);
178 *self = &self[cnt..];
179 Ok(cnt)
180 }
181}
182
183impl BufRead for &[u8] {
184 #[inline]
185 fn fill_buf(&mut self) -> Result<&[u8]> { Ok(self) }
186
187 #[inline]
189 fn consume(&mut self, amount: usize) { *self = &self[amount..] }
190}
191
192pub struct Cursor<T> {
194 inner: T,
195 pos: u64,
196}
197
198impl<T: AsRef<[u8]>> Cursor<T> {
199 #[inline]
201 pub fn new(inner: T) -> Self { Cursor { inner, pos: 0 } }
202
203 #[inline]
205 pub fn position(&self) -> u64 { self.pos }
206
207 #[inline]
214 pub fn set_position(&mut self, position: u64) { self.pos = position; }
215
216 #[inline]
220 pub fn into_inner(self) -> T { self.inner }
221
222 #[inline]
226 pub fn inner(&self) -> &T { &self.inner }
227}
228
229impl<T: AsRef<[u8]>> Read for Cursor<T> {
230 #[inline]
231 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
232 let inner: &[u8] = self.inner.as_ref();
233 let start_pos = self.pos.try_into().unwrap_or(inner.len());
234 let read = core::cmp::min(inner.len().saturating_sub(start_pos), buf.len());
235 buf[..read].copy_from_slice(&inner[start_pos..start_pos + read]);
236 self.pos = self.pos.saturating_add(read.try_into().unwrap_or(u64::MAX ));
237 Ok(read)
238 }
239}
240
241impl<T: AsRef<[u8]>> BufRead for Cursor<T> {
242 #[inline]
243 fn fill_buf(&mut self) -> Result<&[u8]> {
244 let inner: &[u8] = self.inner.as_ref();
245 Ok(&inner[self.pos as usize..])
246 }
247
248 #[inline]
249 fn consume(&mut self, amount: usize) {
250 assert!(amount <= self.inner.as_ref().len());
251 self.pos += amount as u64;
252 }
253}
254
255pub trait Write {
257 fn write(&mut self, buf: &[u8]) -> Result<usize>;
259
260 fn flush(&mut self) -> Result<()>;
263
264 #[inline]
266 fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
267 while !buf.is_empty() {
268 match self.write(buf) {
269 Ok(0) => return Err(ErrorKind::UnexpectedEof.into()),
270 Ok(len) => buf = &buf[len..],
271 Err(e) if e.kind() == ErrorKind::Interrupted => {}
272 Err(e) => return Err(e),
273 }
274 }
275 Ok(())
276 }
277}
278
279impl<T: Write> Write for &'_ mut T {
280 #[inline]
281 fn write(&mut self, buf: &[u8]) -> Result<usize> { (**self).write(buf) }
282
283 #[inline]
284 fn write_all(&mut self, buf: &[u8]) -> Result<()> { (**self).write_all(buf) }
285
286 #[inline]
287 fn flush(&mut self) -> Result<()> { (**self).flush() }
288}
289
290#[cfg(feature = "alloc")]
291impl Write for alloc::vec::Vec<u8> {
292 #[inline]
293 fn write(&mut self, buf: &[u8]) -> Result<usize> {
294 self.extend_from_slice(buf);
295 Ok(buf.len())
296 }
297
298 #[inline]
299 fn flush(&mut self) -> Result<()> { Ok(()) }
300}
301
302impl<'a> Write for &'a mut [u8] {
303 #[inline]
304 fn write(&mut self, buf: &[u8]) -> Result<usize> {
305 let cnt = core::cmp::min(self.len(), buf.len());
306 self[..cnt].copy_from_slice(&buf[..cnt]);
307 *self = &mut core::mem::take(self)[cnt..];
308 Ok(cnt)
309 }
310
311 #[inline]
312 fn flush(&mut self) -> Result<()> { Ok(()) }
313}
314
315pub struct Sink;
319
320impl Write for Sink {
321 #[inline]
322 fn write(&mut self, buf: &[u8]) -> Result<usize> { Ok(buf.len()) }
323
324 #[inline]
325 fn write_all(&mut self, _: &[u8]) -> Result<()> { Ok(()) }
326
327 #[inline]
328 fn flush(&mut self) -> Result<()> { Ok(()) }
329}
330
331#[inline]
333pub fn sink() -> Sink { Sink }
334
335#[cfg(feature = "std")]
339#[inline]
340pub const fn from_std<T>(std_io: T) -> FromStd<T> { FromStd::new(std_io) }
341
342#[cfg(feature = "std")]
346#[inline]
347pub fn from_std_mut<T>(std_io: &mut T) -> &mut FromStd<T> { FromStd::new_mut(std_io) }
348
349#[cfg(test)]
350mod tests {
351 #[cfg(all(not(feature = "std"), feature = "alloc"))]
352 use alloc::{string::ToString, vec};
353
354 use super::*;
355
356 #[test]
357 fn buf_read_fill_and_consume_slice() {
358 let data = [0_u8, 1, 2];
359
360 let mut slice = &data[..];
361
362 let fill = BufRead::fill_buf(&mut slice).unwrap();
363 assert_eq!(fill.len(), 3);
364 assert_eq!(fill, &[0_u8, 1, 2]);
365 slice.consume(2);
366
367 let fill = BufRead::fill_buf(&mut slice).unwrap();
368 assert_eq!(fill.len(), 1);
369 assert_eq!(fill, &[2_u8]);
370 slice.consume(1);
371
372 let fill = BufRead::fill_buf(&mut slice).unwrap();
374 assert!(fill.is_empty());
375 }
376
377 #[test]
378 #[cfg(feature = "alloc")]
379 fn read_to_limit_greater_than_total_length() {
380 let s = "16-byte-string!!".to_string();
381 let mut reader = Cursor::new(&s);
382 let mut buf = vec![];
383
384 let read = reader.read_to_limit(&mut buf, 32).expect("failed to read to limit");
386 assert_eq!(read, s.len());
387 assert_eq!(&buf, s.as_bytes())
388 }
389
390 #[test]
391 #[cfg(feature = "alloc")]
392 fn read_to_limit_less_than_total_length() {
393 let s = "16-byte-string!!".to_string();
394 let mut reader = Cursor::new(&s);
395 let mut buf = vec![];
396
397 let read = reader.read_to_limit(&mut buf, 2).expect("failed to read to limit");
398 assert_eq!(read, 2);
399 assert_eq!(&buf, "16".as_bytes())
400 }
401}