iter_read/lib.rs
1// Copyright (c) 2015-2023 Georg Brandl. Licensed under the Apache License,
2// Version 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>
3// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at
4// your option. This file may not be copied, modified, or distributed except
5// according to those terms.
6
7//! A small crate that provides an adapter to Read from an iterator over bytes.
8//! This is useful if you want to use an API that takes a `Read` instance, but
9//! want to feed it data from an iterator.
10//!
11//! Example:
12//!
13//! ```
14//! use std::io::Read;
15//! use iter_read::IterRead;
16//!
17//! let source = vec![1, 2, 7, 42, 123];
18//! let mut reader = IterRead::new(source.iter());
19//! let mut buf = vec![0; 3];
20//! reader.read_exact(&mut buf).unwrap();
21//! assert_eq!(buf, b"\x01\x02\x07");
22//! ```
23
24#![cfg_attr(feature = "unstable", feature(test))]
25
26use std::io::{Read, Result};
27use std::iter::Fuse;
28
29
30/// Trait that should be implemented for any type which can be used in an
31/// iterator given to `IterRead`.
32pub trait IterReadItem {
33 /// Represents the type of buffer that the adapter will use.
34 /// Can be `()` if no buffer is required.
35 type Buffer: Default;
36
37 /// Implements `Read::read()` for the specific type Self.
38 fn read<I: Iterator<Item=Self>>(target: &mut [u8], it: &mut I, buf: &mut Self::Buffer)
39 -> Result<usize> where Self: Sized;
40}
41
42/// An adapter that allows treating iterators of bytes (and other types that
43/// implement `IterReadItem`) as a `Read`.
44///
45/// `IterReadItem` is implemented for `u8`, `&u8`, `Vec<u8>`, `[u8; N]` and its
46/// borrowed variants as well as `String` and its borrowed variants. It is also
47/// implemented for all iterators that take a `Result` type whose `Ok` value is
48/// an `IterReadItem` and whose `Err` value can be converted to an
49/// `std::io::Error` with `into()`.
50///
51/// For inner types other than `u8` the adapter might need to buffer some
52/// contents of the iterator.
53pub struct IterRead<E: IterReadItem, I: Iterator<Item=E>> {
54 iter: Fuse<I>,
55 buf: E::Buffer,
56}
57
58impl<E: IterReadItem, I: Iterator<Item=E>> IterRead<E, I> {
59 /// Create a new `IterRead` which will read from the specified `Iterator`.
60 pub fn new(iter: I) -> IterRead<E, I> {
61 IterRead { iter: iter.fuse(), buf: Default::default() }
62 }
63
64 /// Unwrap the inner iterator. If the adapter uses buffering, the contents
65 /// of the buffer are lost.
66 pub fn into_inner(self) -> Fuse<I> {
67 self.iter
68 }
69}
70
71impl<E: IterReadItem, I: Iterator<Item=E>> Read for IterRead<E, I> {
72 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
73 E::read(buf, &mut self.iter, &mut self.buf)
74 }
75}
76
77mod impls;
78
79#[cfg(test)]
80mod tests;