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;