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