walker_common/progress/
mod.rs

1//! Progress reporting
2
3use std::future::Future;
4
5pub mod indicatif;
6
7pub trait Progress {
8    type Instance: ProgressBar;
9
10    fn start(&self, work: usize) -> Self::Instance;
11}
12
13pub trait ProgressBar {
14    fn tick(&mut self) -> impl Future<Output = ()> {
15        self.increment(1)
16    }
17
18    fn increment(&mut self, work: usize) -> impl Future<Output = ()>;
19
20    fn finish(self) -> impl Future<Output = ()>;
21
22    fn set_message(&mut self, msg: String) -> impl Future<Output = ()>;
23}
24
25impl Progress for () {
26    type Instance = ();
27
28    fn start(&self, _work: usize) -> Self::Instance {}
29}
30
31pub struct NoOpIter<I>(I)
32where
33    I: Iterator;
34
35impl<I> Iterator for NoOpIter<I>
36where
37    I: Iterator,
38{
39    type Item = I::Item;
40
41    fn next(&mut self) -> Option<Self::Item> {
42        self.0.next()
43    }
44}
45
46impl ProgressBar for () {
47    async fn increment(&mut self, _work: usize) {}
48
49    async fn finish(self) {}
50
51    async fn set_message(&mut self, _msg: String) {}
52}
53
54impl<P: Progress> Progress for Option<P> {
55    type Instance = Option<P::Instance>;
56
57    fn start(&self, work: usize) -> Self::Instance {
58        self.as_ref().map(|progress| progress.start(work))
59    }
60}
61
62impl<P: ProgressBar> ProgressBar for Option<P> {
63    async fn increment(&mut self, work: usize) {
64        if let Some(bar) = self {
65            bar.increment(work).await;
66        }
67    }
68
69    async fn finish(self) {
70        if let Some(bar) = self {
71            bar.finish().await;
72        }
73    }
74
75    async fn set_message(&mut self, msg: String) {
76        if let Some(bar) = self {
77            bar.set_message(msg).await;
78        }
79    }
80}