1use std::time::Instant;
2
3use crate::{messages::MessageLevel, progress, progress::Id, Unit};
4
5pub trait NestedProgress: Progress {
7 type SubProgress: NestedProgress;
9
10 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress;
16
17 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress;
22}
23
24pub trait Count {
26 fn set(&self, step: progress::Step);
31
32 fn step(&self) -> progress::Step;
34
35 fn inc_by(&self, step: progress::Step);
38
39 fn inc(&self) {
42 self.inc_by(1)
43 }
44
45 fn counter(&self) -> StepShared;
50}
51
52pub trait DynNestedProgress: Progress + impls::Sealed {
57 fn add_child(&mut self, name: String) -> BoxedDynNestedProgress;
59
60 fn add_child_with_id(&mut self, name: String, id: Id) -> BoxedDynNestedProgress;
62}
63
64pub struct BoxedDynNestedProgress(Box<dyn DynNestedProgress>);
66
67pub type BoxedProgress = Box<dyn Progress>;
69
70pub struct DynNestedProgressToNestedProgress<T: ?Sized>(pub T);
72
73pub trait Progress: Count + Send + Sync {
79 fn init(&mut self, max: Option<progress::Step>, unit: Option<Unit>);
95
96 fn unit(&self) -> Option<Unit> {
98 None
99 }
100
101 fn max(&self) -> Option<progress::Step> {
103 None
104 }
105
106 fn set_max(&mut self, _max: Option<progress::Step>) -> Option<progress::Step> {
108 None
109 }
110
111 fn set_name(&mut self, name: String);
114
115 fn name(&self) -> Option<String>;
118
119 fn id(&self) -> Id;
122
123 fn message(&self, level: MessageLevel, message: String);
128
129 fn info(&self, message: String) {
131 self.message(MessageLevel::Info, message)
132 }
133 fn done(&self, message: String) {
135 self.message(MessageLevel::Success, message)
136 }
137 fn fail(&self, message: String) {
139 self.message(MessageLevel::Failure, message)
140 }
141 fn show_throughput(&self, start: Instant) {
143 let step = self.step();
144 match self.unit() {
145 Some(unit) => self.show_throughput_with(start, step, unit, MessageLevel::Info),
146 None => {
147 let elapsed = start.elapsed().as_secs_f32();
148 let steps_per_second = (step as f32 / elapsed) as progress::Step;
149 self.info(format!(
150 "done {} items in {:.02}s ({} items/s)",
151 step, elapsed, steps_per_second
152 ))
153 }
154 };
155 }
156
157 fn show_throughput_with(&self, start: Instant, step: progress::Step, unit: Unit, level: MessageLevel) {
159 use std::fmt::Write;
160 let elapsed = start.elapsed().as_secs_f32();
161 let steps_per_second = (step as f32 / elapsed) as progress::Step;
162 let mut buf = String::with_capacity(128);
163 let unit = unit.as_display_value();
164 let push_unit = |buf: &mut String| {
165 buf.push(' ');
166 let len_before_unit = buf.len();
167 unit.display_unit(buf, step).ok();
168 if buf.len() == len_before_unit {
169 buf.pop();
170 }
171 };
172
173 buf.push_str("done ");
174 unit.display_current_value(&mut buf, step, None).ok();
175 push_unit(&mut buf);
176
177 buf.write_fmt(format_args!(" in {:.02}s (", elapsed)).ok();
178 unit.display_current_value(&mut buf, steps_per_second, None).ok();
179 push_unit(&mut buf);
180 buf.push_str("/s)");
181
182 self.message(level, buf);
183 }
184}
185
186use crate::{
187 messages::{Message, MessageCopyState},
188 progress::StepShared,
189};
190
191pub trait WeakRoot {
195 type Root: Root;
197
198 fn upgrade(&self) -> Option<Self::Root>;
200}
201
202pub trait Root {
204 type WeakRoot: WeakRoot;
206
207 fn messages_capacity(&self) -> usize;
209
210 fn num_tasks(&self) -> usize;
213
214 fn sorted_snapshot(&self, out: &mut Vec<(progress::Key, progress::Task)>);
218
219 fn copy_messages(&self, out: &mut Vec<Message>);
222
223 fn copy_new_messages(&self, out: &mut Vec<Message>, prev: Option<MessageCopyState>) -> MessageCopyState;
226
227 fn downgrade(&self) -> Self::WeakRoot;
229}
230
231mod impls {
232 use std::{
233 ops::{Deref, DerefMut},
234 time::Instant,
235 };
236
237 use crate::traits::{BoxedProgress, Progress};
238 use crate::{
239 messages::MessageLevel,
240 progress::{Id, Step, StepShared},
241 BoxedDynNestedProgress, Count, DynNestedProgress, DynNestedProgressToNestedProgress, NestedProgress, Unit,
242 };
243
244 pub trait Sealed {}
245
246 impl<T> Count for &T
247 where
248 T: Count + ?Sized,
249 {
250 fn set(&self, step: Step) {
251 (*self).set(step)
252 }
253
254 fn step(&self) -> Step {
255 (*self).step()
256 }
257
258 fn inc_by(&self, step: Step) {
259 (*self).inc_by(step)
260 }
261
262 fn inc(&self) {
263 (*self).inc()
264 }
265
266 fn counter(&self) -> StepShared {
267 (*self).counter()
268 }
269 }
270
271 impl<T> Count for &mut T
272 where
273 T: Count + ?Sized,
274 {
275 fn set(&self, step: Step) {
276 self.deref().set(step)
277 }
278
279 fn step(&self) -> Step {
280 self.deref().step()
281 }
282
283 fn inc_by(&self, step: Step) {
284 self.deref().inc_by(step)
285 }
286
287 fn inc(&self) {
288 self.deref().inc()
289 }
290
291 fn counter(&self) -> StepShared {
292 self.deref().counter()
293 }
294 }
295
296 impl<T> Progress for &mut T
297 where
298 T: Progress + ?Sized,
299 {
300 fn init(&mut self, max: Option<Step>, unit: Option<Unit>) {
301 self.deref_mut().init(max, unit)
302 }
303
304 fn unit(&self) -> Option<Unit> {
305 self.deref().unit()
306 }
307
308 fn max(&self) -> Option<Step> {
309 self.deref().max()
310 }
311
312 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
313 self.deref_mut().set_max(max)
314 }
315
316 fn set_name(&mut self, name: String) {
317 self.deref_mut().set_name(name)
318 }
319
320 fn name(&self) -> Option<String> {
321 self.deref().name()
322 }
323
324 fn id(&self) -> Id {
325 self.deref().id()
326 }
327
328 fn message(&self, level: MessageLevel, message: String) {
329 self.deref().message(level, message)
330 }
331
332 fn info(&self, message: String) {
333 self.deref().info(message)
334 }
335
336 fn done(&self, message: String) {
337 self.deref().done(message)
338 }
339
340 fn fail(&self, message: String) {
341 self.deref().fail(message)
342 }
343
344 fn show_throughput(&self, start: Instant) {
345 self.deref().show_throughput(start)
346 }
347
348 fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) {
349 self.deref().show_throughput_with(start, step, unit, level)
350 }
351 }
352
353 impl<T> NestedProgress for &mut T
354 where
355 T: NestedProgress + ?Sized,
356 {
357 type SubProgress = T::SubProgress;
358
359 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
360 self.deref_mut().add_child(name)
361 }
362
363 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress {
364 self.deref_mut().add_child_with_id(name, id)
365 }
366 }
367
368 impl<T> Sealed for T where T: NestedProgress + ?Sized {}
369
370 impl<T, SubP> DynNestedProgress for T
371 where
372 T: NestedProgress<SubProgress = SubP> + ?Sized,
373 SubP: NestedProgress + 'static,
374 {
375 fn add_child(&mut self, name: String) -> BoxedDynNestedProgress {
376 BoxedDynNestedProgress::new(self.add_child(name))
377 }
378
379 fn add_child_with_id(&mut self, name: String, id: Id) -> BoxedDynNestedProgress {
380 BoxedDynNestedProgress::new(self.add_child_with_id(name, id))
381 }
382 }
383
384 impl BoxedDynNestedProgress {
385 pub fn new(progress: impl DynNestedProgress + 'static) -> Self {
387 Self(Box::new(progress))
388 }
389 }
390
391 impl Progress for BoxedDynNestedProgress {
392 fn init(&mut self, max: Option<Step>, unit: Option<Unit>) {
393 self.0.init(max, unit)
394 }
395
396 fn unit(&self) -> Option<Unit> {
397 self.0.unit()
398 }
399
400 fn max(&self) -> Option<Step> {
401 self.0.max()
402 }
403
404 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
405 self.0.set_max(max)
406 }
407
408 fn set_name(&mut self, name: String) {
409 self.0.set_name(name)
410 }
411
412 fn name(&self) -> Option<String> {
413 self.0.name()
414 }
415
416 fn id(&self) -> Id {
417 self.0.id()
418 }
419
420 fn message(&self, level: MessageLevel, message: String) {
421 self.0.message(level, message)
422 }
423
424 fn show_throughput(&self, start: Instant) {
425 self.0.show_throughput(start)
426 }
427
428 fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) {
429 self.0.show_throughput_with(start, step, unit, level)
430 }
431 }
432
433 impl Progress for BoxedProgress {
434 fn init(&mut self, max: Option<Step>, unit: Option<Unit>) {
435 self.deref_mut().init(max, unit)
436 }
437
438 fn unit(&self) -> Option<Unit> {
439 self.deref().unit()
440 }
441
442 fn max(&self) -> Option<Step> {
443 self.deref().max()
444 }
445
446 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
447 self.deref_mut().set_max(max)
448 }
449
450 fn set_name(&mut self, name: String) {
451 self.deref_mut().set_name(name)
452 }
453
454 fn name(&self) -> Option<String> {
455 self.deref().name()
456 }
457
458 fn id(&self) -> Id {
459 self.deref().id()
460 }
461
462 fn message(&self, level: MessageLevel, message: String) {
463 self.deref().message(level, message)
464 }
465
466 fn show_throughput(&self, start: Instant) {
467 self.deref().show_throughput(start)
468 }
469
470 fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) {
471 self.deref().show_throughput_with(start, step, unit, level)
472 }
473 }
474
475 impl Count for BoxedDynNestedProgress {
476 fn set(&self, step: Step) {
477 self.0.set(step)
478 }
479
480 fn step(&self) -> Step {
481 self.0.step()
482 }
483
484 fn inc_by(&self, step: Step) {
485 self.0.inc_by(step)
486 }
487
488 fn inc(&self) {
489 self.0.inc()
490 }
491
492 fn counter(&self) -> StepShared {
493 self.0.counter()
494 }
495 }
496
497 impl Count for BoxedProgress {
498 fn set(&self, step: Step) {
499 self.deref().set(step)
500 }
501
502 fn step(&self) -> Step {
503 self.deref().step()
504 }
505
506 fn inc_by(&self, step: Step) {
507 self.deref().inc_by(step)
508 }
509
510 fn inc(&self) {
511 self.deref().inc()
512 }
513
514 fn counter(&self) -> StepShared {
515 self.deref().counter()
516 }
517 }
518
519 impl NestedProgress for BoxedDynNestedProgress {
520 type SubProgress = Self;
521
522 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
523 self.0.add_child(name.into())
524 }
525
526 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress {
527 self.0.add_child_with_id(name.into(), id)
528 }
529 }
530
531 impl<T> Progress for DynNestedProgressToNestedProgress<T>
532 where
533 T: ?Sized + Progress,
534 {
535 fn init(&mut self, max: Option<Step>, unit: Option<Unit>) {
536 self.0.init(max, unit)
537 }
538
539 fn unit(&self) -> Option<Unit> {
540 self.0.unit()
541 }
542
543 fn max(&self) -> Option<Step> {
544 self.0.max()
545 }
546
547 fn set_max(&mut self, max: Option<Step>) -> Option<Step> {
548 self.0.set_max(max)
549 }
550
551 fn set_name(&mut self, name: String) {
552 self.0.set_name(name)
553 }
554
555 fn name(&self) -> Option<String> {
556 self.0.name()
557 }
558
559 fn id(&self) -> Id {
560 self.0.id()
561 }
562
563 fn message(&self, level: MessageLevel, message: String) {
564 self.0.message(level, message)
565 }
566
567 fn show_throughput(&self, start: Instant) {
568 self.0.show_throughput(start)
569 }
570
571 fn show_throughput_with(&self, start: Instant, step: Step, unit: Unit, level: MessageLevel) {
572 self.0.show_throughput_with(start, step, unit, level)
573 }
574 }
575
576 impl<T> Count for DynNestedProgressToNestedProgress<T>
577 where
578 T: ?Sized + Count,
579 {
580 fn set(&self, step: Step) {
581 self.0.set(step)
582 }
583
584 fn step(&self) -> Step {
585 self.0.step()
586 }
587
588 fn inc_by(&self, step: Step) {
589 self.0.inc_by(step)
590 }
591
592 fn inc(&self) {
593 self.0.inc()
594 }
595
596 fn counter(&self) -> StepShared {
597 self.0.counter()
598 }
599 }
600
601 impl<T> NestedProgress for DynNestedProgressToNestedProgress<T>
602 where
603 T: DynNestedProgress + ?Sized,
604 {
605 type SubProgress = BoxedDynNestedProgress;
606
607 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
608 self.0.add_child(name.into())
609 }
610
611 fn add_child_with_id(&mut self, name: impl Into<String>, id: Id) -> Self::SubProgress {
612 self.0.add_child_with_id(name.into(), id)
613 }
614 }
615}