1use std::io::{self, Read, Write};
19
20use crate::Progress;
21
22pub struct ProgressReader<R> {
24 inner: R,
25 progress: Progress,
26}
27
28impl<R> ProgressReader<R> {
29 pub const fn new(inner: R, progress: Progress) -> Self {
31 Self { inner, progress }
32 }
33}
34
35impl<R: Read> Read for ProgressReader<R> {
36 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
37 let n = self.inner.read(buf)?;
38 self.progress.inc(n as u64);
40 Ok(n)
41 }
42}
43
44pub struct ProgressWriter<W> {
46 inner: W,
47 progress: Progress,
48}
49
50impl<W> ProgressWriter<W> {
51 pub const fn new(inner: W, progress: Progress) -> Self {
53 Self { inner, progress }
54 }
55}
56
57impl<W: Write> Write for ProgressWriter<W> {
58 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
59 let n = self.inner.write(buf)?;
60 self.progress.inc(n as u64);
61 Ok(n)
62 }
63
64 fn flush(&mut self) -> io::Result<()> {
65 self.inner.flush()
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use std::io::{Cursor, Read as _, Write as _};
72
73 use crate::io::{ProgressReader, ProgressWriter};
74
75 use super::Progress;
76
77 #[test]
80 fn test_io_reader() {
81 let data = vec![0u8; 100];
82 let p = Progress::new_pb("read", 100u64);
83 let mut reader = ProgressReader::new(Cursor::new(&data), p.clone());
84
85 let mut buf = [0u8; 10];
86 reader.read_exact(&mut buf).unwrap();
87
88 assert_eq!(p.get_pos(), 10);
89 }
90
91 #[test]
94 fn test_io_writer() {
95 let p = Progress::new_pb("write", 50u64);
96 let mut writer = ProgressWriter::new(Vec::new(), p.clone());
97
98 writer.write_all(&[1, 2, 3, 4, 5]).unwrap();
99
100 assert_eq!(p.get_pos(), 5);
101 }
102}