1use std::io;
3
4#[cfg(feature = "progress-unit-bytes")]
5pub use bytesize;
6pub use prodash::{
7 self,
8 messages::MessageLevel,
9 progress::{
10 AtomicStep, Discard, DoOrDiscard, Either, Id, Step, StepShared, Task, ThroughputOnDrop, Value, UNKNOWN,
11 },
12 unit, BoxedDynNestedProgress, Count, DynNestedProgress, DynNestedProgressToNestedProgress, NestedProgress,
13 Progress, Unit,
14};
15#[cfg(not(feature = "progress-unit-bytes"))]
17pub mod bytesize {
18 pub struct ByteSize(pub u64);
20
21 impl std::fmt::Display for ByteSize {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 self.0.fmt(f)
24 }
25 }
26}
27
28#[cfg(feature = "progress-unit-bytes")]
30pub fn bytes() -> Option<Unit> {
31 Some(unit::dynamic_and_mode(
32 unit::Bytes,
33 unit::display::Mode::with_throughput().and_percentage(),
34 ))
35}
36
37#[cfg(not(feature = "progress-unit-bytes"))]
39pub fn bytes() -> Option<Unit> {
40 Some(unit::label_and_mode(
41 "B",
42 unit::display::Mode::with_throughput().and_percentage(),
43 ))
44}
45
46pub fn count(name: &'static str) -> Option<Unit> {
48 count_with_decimals(name, 1)
49}
50
51#[cfg(feature = "progress-unit-human-numbers")]
54pub fn count_with_decimals(name: &'static str, decimals: usize) -> Option<Unit> {
55 Some(unit::dynamic_and_mode(
56 unit::Human::new(
57 {
58 let mut f = unit::human::Formatter::new();
59 f.with_decimals(decimals);
60 f
61 },
62 name,
63 ),
64 unit::display::Mode::with_throughput().and_percentage(),
65 ))
66}
67
68#[cfg(not(feature = "progress-unit-human-numbers"))]
71pub fn count_with_decimals(name: &'static str, _decimals: usize) -> Option<Unit> {
72 Some(unit::label_and_mode(
73 name,
74 unit::display::Mode::with_throughput().and_percentage(),
75 ))
76}
77
78pub fn steps() -> Option<Unit> {
80 Some(unit::dynamic(unit::Range::new("steps")))
81}
82
83pub struct Read<T, P> {
85 pub inner: T,
87 pub progress: P,
89}
90
91impl<T, P> io::Read for Read<T, P>
92where
93 T: io::Read,
94 P: Progress,
95{
96 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
97 let bytes_read = self.inner.read(buf)?;
98 self.progress.inc_by(bytes_read);
99 Ok(bytes_read)
100 }
101}
102
103impl<T, P> io::BufRead for Read<T, P>
104where
105 T: io::BufRead,
106 P: Progress,
107{
108 fn fill_buf(&mut self) -> io::Result<&[u8]> {
109 self.inner.fill_buf()
110 }
111
112 fn consume(&mut self, amt: usize) {
113 self.inner.consume(amt);
114 }
115}
116
117pub struct Write<T, P> {
121 pub inner: T,
123 pub progress: P,
125}
126
127impl<T, P> io::Write for Write<T, P>
128where
129 T: io::Write,
130 P: Progress,
131{
132 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
133 let written = self.inner.write(buf)?;
134 self.progress.inc_by(written);
135 Ok(written)
136 }
137
138 fn flush(&mut self) -> io::Result<()> {
139 self.inner.flush()
140 }
141}
142
143impl<T, P> io::Seek for Write<T, P>
144where
145 T: io::Seek,
146{
147 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
148 self.inner.seek(pos)
149 }
150}