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