1use std::time::Duration;
2use indicatif::{ProgressBar as PBar, ProgressStyle};
3
4use crate::result::Result;
5
6pub trait ProgressTrait {
7 type ProgressResultType;
8
9 fn update(&self, msg: &str) -> Result<Self::ProgressResultType>;
10 fn done(&self, msg: &str) -> Result<Self::ProgressResultType>;
11 fn done_without_indicator(&self, msg: &str) -> Result<Self::ProgressResultType>;
12}
13
14pub struct ProgressBar {
15 bar: PBar,
16}
17
18impl ProgressBar {
19 pub fn new() -> Self {
20 let bar = PBar::new_spinner();
21 bar.enable_steady_tick(Duration::from_millis(80));
22 bar.set_style(
23 ProgressStyle::default_spinner()
24 .tick_strings(&["⢹", "⢺", "⢼", "⣸", "⣇", "⡧", "⡗", "✔"])
26 .template("{spinner} {msg}").unwrap_or(ProgressStyle::default_spinner()),
27 );
28
29 Self { bar }
30 }
31}
32
33impl ProgressTrait for ProgressBar {
34 type ProgressResultType = ();
35
36 fn update(&self, msg: &str) -> Result<Self::ProgressResultType> {
37 self.bar.set_message(msg.to_owned());
38
39 Ok(())
40 }
41
42 fn done(&self, msg: &str) -> Result<Self::ProgressResultType> {
43 self.bar.finish_with_message(msg.to_owned());
44
45 Ok(())
46 }
47
48 fn done_without_indicator(&self, msg: &str) -> Result<Self::ProgressResultType> {
49 self.bar.finish_and_clear();
50 if !msg.is_empty() {
51 println!("{}", msg);
52 }
53
54 Ok(())
55 }
56}