akar_common/
progress_bar.rs1use indicatif::{ProgressBar as IndiProgressBar, ProgressStyle};
2use std::sync::Arc;
3use std::sync::atomic::{AtomicBool, Ordering};
4use std::time::Duration;
5
6pub struct AkarProgress {
24 inner: Option<IndiProgressBar>,
25 cancelled: Arc<AtomicBool>,
26}
27
28impl AkarProgress {
29 pub fn new(msg: &str, total: Option<u64>) -> Self {
34 let cancelled = Arc::new(AtomicBool::new(false));
35 let inner = match total {
36 Some(n) => {
37 let pb = IndiProgressBar::new(n);
38 pb.set_style(
39 ProgressStyle::default_bar()
40 .template("{msg} [{bar:40}] {pos}/{len} ({eta})")
41 .unwrap()
42 .progress_chars("=> "),
43 );
44 pb.set_message(msg.to_owned());
45 Some(pb)
46 }
47 None => {
48 let pb = IndiProgressBar::new_spinner();
49 pb.set_style(
50 ProgressStyle::default_spinner()
51 .template("{spinner:.green} {msg}")
52 .unwrap(),
53 );
54 pb.set_message(msg.to_owned());
55 pb.enable_steady_tick(Duration::from_millis(100));
56 Some(pb)
57 }
58 };
59 Self { inner, cancelled }
60 }
61
62 pub fn inc(&self) {
64 if let Some(ref pb) = self.inner {
65 pb.inc(1);
66 }
67 }
68
69 pub fn inc_by(&self, delta: u64) {
71 if let Some(ref pb) = self.inner {
72 pb.inc(delta);
73 }
74 }
75
76 pub fn set_pos(&self, pos: u64) {
78 if let Some(ref pb) = self.inner {
79 pb.set_position(pos);
80 }
81 }
82
83 pub fn set_message(&self, msg: &str) {
85 if let Some(ref pb) = self.inner {
86 pb.set_message(msg.to_owned());
87 }
88 }
89
90 pub fn finish(&self, msg: &str) {
92 if let Some(ref pb) = self.inner {
93 pb.finish_with_message(msg.to_owned());
94 }
95 }
96
97 pub fn abort(&self) {
99 if let Some(ref pb) = self.inner {
100 pb.abandon();
101 }
102 }
103
104 pub fn cancel(&self) {
107 self.cancelled.store(true, Ordering::Relaxed);
108 self.finish("Cancelled.");
109 }
110
111 pub fn is_cancelled(&self) -> bool {
113 self.cancelled.load(Ordering::Relaxed)
114 }
115
116 pub fn cancelled_flag(&self) -> Arc<AtomicBool> {
118 self.cancelled.clone()
119 }
120}
121
122impl Drop for AkarProgress {
123 fn drop(&mut self) {
124 if let Some(ref pb) = self.inner {
126 pb.finish_and_clear();
127 }
128 }
129}