Skip to main content

hexz_ops/
progress.rs

1//! Progress reporting for long-running pack operations.
2//!
3//! Provides a consistent progress bar interface using indicatif.
4
5use indicatif::{ProgressBar, ProgressStyle};
6
7/// Progress tracker for packing operations.
8pub struct PackProgress {
9    bar: ProgressBar,
10}
11
12impl std::fmt::Debug for PackProgress {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        f.debug_struct("PackProgress").finish_non_exhaustive()
15    }
16}
17
18impl PackProgress {
19    /// Create a new progress bar
20    ///
21    /// # Arguments
22    ///
23    /// * `total_bytes` - Total bytes to process
24    /// * `message` - Initial message to display
25    pub fn new(total_bytes: u64, message: &str) -> Self {
26        let bar = ProgressBar::new(total_bytes);
27        if let Ok(style) = ProgressStyle::default_bar()
28            .template("{msg} {bar:40.cyan/blue} {bytes}/{total_bytes} ({bytes_per_sec}, {eta})")
29        {
30            bar.set_style(style.progress_chars("█▓▒░ "));
31        }
32        bar.set_message(message.to_string());
33
34        Self { bar }
35    }
36
37    /// Increment progress by delta bytes
38    pub fn inc(&self, delta: u64) {
39        self.bar.inc(delta);
40    }
41
42    /// Set current position directly
43    pub fn set_position(&self, pos: u64) {
44        self.bar.set_position(pos);
45    }
46
47    /// Finish with success message
48    pub fn finish(&self) {
49        self.bar.finish_with_message("Packing complete");
50    }
51
52    /// Finish with custom message
53    pub fn finish_with_message(&self, msg: &str) {
54        self.bar.finish_with_message(msg.to_string());
55    }
56
57    /// Update the message
58    pub fn set_message(&self, msg: &str) {
59        self.bar.set_message(msg.to_string());
60    }
61}
62
63impl Drop for PackProgress {
64    fn drop(&mut self) {
65        if !self.bar.is_finished() {
66            self.bar.abandon();
67        }
68    }
69}