walker_common/progress/
mod.rs1use 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}