use std::io::{self, Read, Write};
use crate::Progress;
pub struct ProgressReader<R> {
inner: R,
progress: Progress,
}
impl<R> ProgressReader<R> {
pub const fn new(inner: R, progress: Progress) -> Self {
Self { inner, progress }
}
}
impl<R: Read> Read for ProgressReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let n = self.inner.read(buf)?;
self.progress.inc(n as u64);
Ok(n)
}
}
pub struct ProgressWriter<W> {
inner: W,
progress: Progress,
}
impl<W> ProgressWriter<W> {
pub const fn new(inner: W, progress: Progress) -> Self {
Self { inner, progress }
}
}
impl<W: Write> Write for ProgressWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let n = self.inner.write(buf)?;
self.progress.inc(n as u64);
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
#[cfg(test)]
mod tests {
use std::io::{Cursor, Read as _, Write as _};
use crate::io::{ProgressReader, ProgressWriter};
use super::Progress;
#[test]
fn test_io_reader() {
let data = vec![0u8; 100];
let p = Progress::new_pb("read", 100u64);
let mut reader = ProgressReader::new(Cursor::new(&data), p.clone());
let mut buf = [0u8; 10];
reader.read_exact(&mut buf).unwrap();
assert_eq!(p.get_pos(), 10);
}
#[test]
fn test_io_writer() {
let p = Progress::new_pb("write", 50u64);
let mut writer = ProgressWriter::new(Vec::new(), p.clone());
writer.write_all(&[1, 2, 3, 4, 5]).unwrap();
assert_eq!(p.get_pos(), 5);
}
}