vault_audit_tools/utils/
progress.rs

1//! Progress bar utilities using indicatif
2//!
3//! Provides a wrapper around indicatif's `ProgressBar` for consistent
4//! progress reporting across all commands.
5
6use indicatif::{ProgressBar as IndicatifBar, ProgressStyle};
7
8/// Progress bar wrapper for displaying processing status
9pub struct ProgressBar {
10    bar: IndicatifBar,
11}
12
13impl ProgressBar {
14    /// Create a new progress bar with known total
15    pub fn new(total: usize, label: &str) -> Self {
16        let bar = IndicatifBar::new(total as u64);
17        bar.set_style(
18            ProgressStyle::default_bar()
19                .template(
20                    "{msg} [{bar:40.cyan/blue}] {percent:>3}% ({pos}/{len}) ({per_sec}) {eta}",
21                )
22                .expect("Invalid progress bar template")
23                .progress_chars("█░"),
24        );
25        bar.set_message(label.to_string());
26
27        Self { bar }
28    }
29
30    /// Create a new progress bar with unknown total (spinner mode)
31    #[allow(dead_code)]
32    pub fn new_spinner(label: &str) -> Self {
33        let bar = IndicatifBar::new_spinner();
34        bar.set_style(
35            ProgressStyle::default_spinner()
36                .template("{msg} {spinner} {pos}")
37                .expect("Invalid spinner template"),
38        );
39        bar.set_message(label.to_string());
40
41        Self { bar }
42    }
43
44    /// Update progress
45    pub fn update(&self, current: usize) {
46        self.bar.set_position(current as u64);
47    }
48
49    /// Increment progress by the given amount
50    pub fn inc(&self, delta: u64) {
51        self.bar.inc(delta);
52    }
53
54    /// Force render (indicatif handles this automatically)
55    #[allow(dead_code)]
56    pub fn render(&self) {
57        // indicatif handles rendering automatically
58        self.bar.tick();
59    }
60
61    /// Finish the progress bar
62    pub fn finish(&self) {
63        self.bar.finish();
64    }
65
66    /// Finish with custom message
67    pub fn finish_with_message(&self, message: &str) {
68        self.bar.finish_with_message(message.to_string());
69    }
70
71    /// Print a message above the progress bar without disturbing it
72    pub fn println<S: AsRef<str>>(&self, msg: S) {
73        self.bar.println(msg.as_ref());
74    }
75}