use std::io::{self, Read};
pub struct Chunks<R> {
reader: R,
size: usize,
}
impl<R: Read> Chunks<R> {
pub fn from(reader: R, size: usize) -> Self {
assert_ne!(size, 0, "chunk size cannot be zero");
Self { reader, size }
}
}
impl<B: Read> Iterator for Chunks<B> {
type Item = io::Result<Vec<u8>>;
fn next(&mut self) -> Option<Self::Item> {
let mut chunk = vec![0; self.size];
let mut read = 0;
while read < self.size {
match self.reader.read(&mut chunk[read..]) {
Ok(0) => break,
Ok(r) => read += r,
Err(e) => return Some(Err(e)),
}
}
if read > 0 {
chunk.truncate(read);
Some(Ok(chunk))
} else {
None
}
}
}
pub trait ChunkRead
where
Self: Read + Sized,
{
fn chunks(self, size: usize) -> Chunks<Self> {
Chunks::from(self, size)
}
}
impl<R: Read> ChunkRead for R {}