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    fn println(&self, #[allow(unused_variables)] message: &str) {}
13}
14
15pub trait ProgressBar {
16    fn tick(&mut self) -> impl Future<Output = ()> {
17        self.increment(1)
18    }
19
20    fn increment(&mut self, work: usize) -> impl Future<Output = ()>;
21
22    fn finish(self) -> impl Future<Output = ()>;
23
24    fn set_message(&mut self, msg: String) -> impl Future<Output = ()>;
25}
26
27impl Progress for () {
28    type Instance = ();
29
30    fn start(&self, _work: usize) -> Self::Instance {}
31
32    fn println(&self, message: &str) {
33        println!("{message}");
34    }
35}
36
37pub struct NoOpIter<I>(I)
38where
39    I: Iterator;
40
41impl<I> Iterator for NoOpIter<I>
42where
43    I: Iterator,
44{
45    type Item = I::Item;
46
47    fn next(&mut self) -> Option<Self::Item> {
48        self.0.next()
49    }
50}
51
52impl ProgressBar for () {
53    async fn increment(&mut self, _work: usize) {}
54
55    async fn finish(self) {}
56
57    async fn set_message(&mut self, _msg: String) {}
58}
59
60impl<P: Progress> Progress for Option<P> {
61    type Instance = Option<P::Instance>;
62
63    fn start(&self, work: usize) -> Self::Instance {
64        self.as_ref().map(|progress| progress.start(work))
65    }
66
67    fn println(&self, message: &str) {
68        if let Some(progress) = self {
69            progress.println(message)
70        } else {
71            println!("{message}");
72        }
73    }
74}
75
76impl<P: ProgressBar> ProgressBar for Option<P> {
77    async fn increment(&mut self, work: usize) {
78        if let Some(bar) = self {
79            bar.increment(work).await;
80        }
81    }
82
83    async fn finish(self) {
84        if let Some(bar) = self {
85            bar.finish().await;
86        }
87    }
88
89    async fn set_message(&mut self, msg: String) {
90        if let Some(bar) = self {
91            bar.set_message(msg).await;
92        }
93    }
94}