1use std::io;
3
4pub use prodash;
5pub use prodash::{
6 messages::MessageLevel,
7 progress::{Discard, DoOrDiscard, Either, Id, Step, StepShared, Task, ThroughputOnDrop, Value, UNKNOWN},
8 unit, Progress, Unit,
9};
10
11pub fn bytes() -> Option<Unit> {
13 Some(unit::dynamic_and_mode(
14 unit::Bytes,
15 unit::display::Mode::with_throughput().and_percentage(),
16 ))
17}
18
19pub fn count(name: &'static str) -> Option<Unit> {
21 Some(unit::dynamic_and_mode(
22 unit::Human::new(
23 {
24 let mut f = unit::human::Formatter::new();
25 f.with_decimals(1);
26 f
27 },
28 name,
29 ),
30 unit::display::Mode::with_throughput().and_percentage(),
31 ))
32}
33
34pub fn steps() -> Option<Unit> {
36 Some(unit::dynamic(unit::Range::new("steps")))
37}
38
39pub struct Read<T, P> {
41 pub inner: T,
43 pub progress: P,
45}
46
47impl<T, P> io::Read for Read<T, P>
48where
49 T: io::Read,
50 P: Progress,
51{
52 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
53 let bytes_read = self.inner.read(buf)?;
54 self.progress.inc_by(bytes_read);
55 Ok(bytes_read)
56 }
57}
58
59impl<T, P> io::BufRead for Read<T, P>
60where
61 T: io::BufRead,
62 P: Progress,
63{
64 fn fill_buf(&mut self) -> io::Result<&[u8]> {
65 self.inner.fill_buf()
66 }
67
68 fn consume(&mut self, amt: usize) {
69 self.inner.consume(amt)
70 }
71}
72
73pub struct Write<T, P> {
77 pub inner: T,
79 pub progress: P,
81}
82
83impl<T, P> io::Write for Write<T, P>
84where
85 T: io::Write,
86 P: Progress,
87{
88 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
89 let written = self.inner.write(buf)?;
90 self.progress.inc_by(written);
91 Ok(written)
92 }
93
94 fn flush(&mut self) -> io::Result<()> {
95 self.inner.flush()
96 }
97}