1use crate::{messages::MessageLevel, progress::Id, Count, NestedProgress, Progress, Unit};
2use std::sync::atomic::AtomicUsize;
3use std::sync::Arc;
4
5pub struct Discard;
7
8impl Count for Discard {
9 fn set(&self, _step: usize) {}
10
11 fn step(&self) -> usize {
12 0
13 }
14
15 fn inc_by(&self, _step: usize) {}
16
17 fn counter(&self) -> StepShared {
18 Arc::new(AtomicUsize::default())
19 }
20}
21
22impl Progress for Discard {
23 fn init(&mut self, _max: Option<usize>, _unit: Option<Unit>) {}
24
25 fn set_max(&mut self, _max: Option<Step>) -> Option<Step> {
26 None
27 }
28 fn set_name(&mut self, _name: String) {}
29
30 fn name(&self) -> Option<String> {
31 None
32 }
33
34 fn id(&self) -> Id {
35 crate::progress::UNKNOWN
36 }
37
38 fn message(&self, _level: MessageLevel, _message: String) {}
39}
40
41impl NestedProgress for Discard {
42 type SubProgress = Self;
43
44 fn add_child(&mut self, _name: impl Into<String>) -> Self {
45 Discard
46 }
47
48 fn add_child_with_id(&mut self, _name: impl Into<String>, _id: Id) -> Self {
49 Discard
50 }
51}
52
53#[allow(missing_docs)]
59pub enum Either<L, R> {
60 Left(L),
61 Right(R),
62}
63
64impl<L, R> Count for Either<L, R>
65where
66 L: Count,
67 R: Count,
68{
69 fn set(&self, step: usize) {
70 match self {
71 Either::Left(l) => l.set(step),
72 Either::Right(r) => r.set(step),
73 }
74 }
75 fn step(&self) -> usize {
76 match self {
77 Either::Left(l) => l.step(),
78 Either::Right(r) => r.step(),
79 }
80 }
81 fn inc_by(&self, step: usize) {
82 match self {
83 Either::Left(l) => l.inc_by(step),
84 Either::Right(r) => r.inc_by(step),
85 }
86 }
87 fn counter(&self) -> StepShared {
88 match self {
89 Either::Left(l) => l.counter(),
90 Either::Right(r) => r.counter(),
91 }
92 }
93}
94
95impl<L, R> Progress for Either<L, R>
96where
97 L: Progress,
98 R: Progress,
99{
100 fn init(&mut self, max: Option<usize>, unit: Option<Unit>) {
101 match self {
102 Either::Left(l) => l.init(max, unit),
103 Either::Right(r) => r.init(max, unit),
104 }
105 }
106
107 fn unit(&self) -> Option<Unit> {
108 match self {
109 Either::Left(l) => l.unit(),
110 Either::Right(r) => r.unit(),
111 }
112 }
113
114 fn max(&self) -> Option<usize> {
115 match self {
116 Either::Left(l) => l.max(),
117 Either::Right(r) => r.max(),
118 }
119 }
120
121 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
122 match self {
123 Either::Left(l) => l.set_max(max),
124 Either::Right(r) => r.set_max(max),
125 }
126 }
127
128 fn set_name(&mut self, name: String) {
129 match self {
130 Either::Left(l) => l.set_name(name),
131 Either::Right(r) => r.set_name(name),
132 }
133 }
134
135 fn name(&self) -> Option<String> {
136 match self {
137 Either::Left(l) => l.name(),
138 Either::Right(r) => r.name(),
139 }
140 }
141
142 fn id(&self) -> Id {
143 match self {
144 Either::Left(l) => l.id(),
145 Either::Right(r) => r.id(),
146 }
147 }
148
149 fn message(&self, level: MessageLevel, message: String) {
150 match self {
151 Either::Left(l) => l.message(level, message),
152 Either::Right(r) => r.message(level, message),
153 }
154 }
155}
156
157impl<L, R> NestedProgress for Either<L, R>
158where
159 L: NestedProgress,
160 R: NestedProgress,
161{
162 type SubProgress = Either<L::SubProgress, R::SubProgress>;
163
164 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
165 match self {
166 Either::Left(l) => Either::Left(l.add_child(name)),
167 Either::Right(r) => Either::Right(r.add_child(name)),
168 }
169 }
170
171 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress {
172 match self {
173 Either::Left(l) => Either::Left(l.add_child_with_id(name, id)),
174 Either::Right(r) => Either::Right(r.add_child_with_id(name, id)),
175 }
176 }
177}
178
179pub struct DoOrDiscard<T>(Either<T, Discard>);
181
182impl<T> From<Option<T>> for DoOrDiscard<T>
183where
184 T: NestedProgress,
185{
186 fn from(p: Option<T>) -> Self {
187 match p {
188 Some(p) => DoOrDiscard(Either::Left(p)),
189 None => DoOrDiscard(Either::Right(Discard)),
190 }
191 }
192}
193
194impl<T: NestedProgress> DoOrDiscard<T> {
195 pub fn into_inner(self) -> Option<T> {
197 match self {
198 DoOrDiscard(Either::Left(p)) => Some(p),
199 DoOrDiscard(Either::Right(_)) => None,
200 }
201 }
202
203 pub fn take(&mut self) -> Option<T> {
205 let this = std::mem::replace(self, DoOrDiscard::from(None));
206 match this {
207 DoOrDiscard(Either::Left(p)) => Some(p),
208 DoOrDiscard(Either::Right(_)) => None,
209 }
210 }
211}
212
213impl<T> Count for DoOrDiscard<T>
214where
215 T: Count,
216{
217 fn set(&self, step: usize) {
218 self.0.set(step)
219 }
220 fn step(&self) -> usize {
221 self.0.step()
222 }
223
224 fn inc_by(&self, step: usize) {
225 self.0.inc_by(step)
226 }
227
228 fn counter(&self) -> StepShared {
229 self.0.counter()
230 }
231}
232
233impl<T> Progress for DoOrDiscard<T>
234where
235 T: Progress,
236{
237 fn init(&mut self, max: Option<usize>, unit: Option<Unit>) {
238 self.0.init(max, unit)
239 }
240
241 fn unit(&self) -> Option<Unit> {
242 self.0.unit()
243 }
244
245 fn max(&self) -> Option<usize> {
246 self.0.max()
247 }
248
249 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
250 self.0.set_max(max)
251 }
252
253 fn set_name(&mut self, name: String) {
254 self.0.set_name(name);
255 }
256
257 fn name(&self) -> Option<String> {
258 self.0.name()
259 }
260
261 fn id(&self) -> Id {
262 self.0.id()
263 }
264
265 fn message(&self, level: MessageLevel, message: String) {
266 self.0.message(level, message)
267 }
268}
269
270impl<T> NestedProgress for DoOrDiscard<T>
271where
272 T: NestedProgress,
273{
274 type SubProgress = DoOrDiscard<T::SubProgress>;
275
276 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
277 DoOrDiscard(self.0.add_child(name))
278 }
279
280 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress {
281 DoOrDiscard(self.0.add_child_with_id(name, id))
282 }
283}
284
285use std::time::Instant;
286
287use crate::progress::{Step, StepShared};
288
289pub struct ThroughputOnDrop<T: NestedProgress>(T, Instant);
291
292impl<T: NestedProgress> ThroughputOnDrop<T> {
293 pub fn new(inner: T) -> Self {
295 ThroughputOnDrop(inner, Instant::now())
296 }
297}
298
299impl<T: NestedProgress> Count for ThroughputOnDrop<T> {
300 fn set(&self, step: usize) {
301 self.0.set(step)
302 }
303
304 fn step(&self) -> usize {
305 self.0.step()
306 }
307
308 fn inc_by(&self, step: usize) {
309 self.0.inc_by(step)
310 }
311
312 fn counter(&self) -> StepShared {
313 self.0.counter()
314 }
315}
316
317impl<T: NestedProgress> Progress for ThroughputOnDrop<T> {
318 fn init(&mut self, max: Option<usize>, unit: Option<Unit>) {
319 self.0.init(max, unit)
320 }
321
322 fn unit(&self) -> Option<Unit> {
323 self.0.unit()
324 }
325
326 fn max(&self) -> Option<usize> {
327 self.0.max()
328 }
329
330 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
331 self.0.set_max(max)
332 }
333
334 fn set_name(&mut self, name: String) {
335 self.0.set_name(name)
336 }
337
338 fn name(&self) -> Option<String> {
339 self.0.name()
340 }
341
342 fn id(&self) -> Id {
343 self.0.id()
344 }
345
346 fn message(&self, level: MessageLevel, message: String) {
347 self.0.message(level, message)
348 }
349}
350
351impl<T: NestedProgress> NestedProgress for ThroughputOnDrop<T> {
352 type SubProgress = ThroughputOnDrop<T::SubProgress>;
353
354 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
355 ThroughputOnDrop::new(self.0.add_child(name))
356 }
357
358 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress {
359 ThroughputOnDrop::new(self.0.add_child_with_id(name, id))
360 }
361}
362
363impl<T: NestedProgress> Drop for ThroughputOnDrop<T> {
364 fn drop(&mut self) {
365 self.0.show_throughput(self.1)
366 }
367}