Skip to main content

oxigeo_cli/util/
progress.rs

1//! Progress bar utilities for long-running operations
2
3use indicatif::{ProgressBar, ProgressStyle};
4use std::time::Duration;
5
6/// Create a progress bar for processing operations
7pub fn create_progress_bar(total: u64, message: &str) -> ProgressBar {
8    let pb = ProgressBar::new(total);
9    pb.set_style(
10        ProgressStyle::default_bar()
11            .template("{msg} [{bar:40.cyan/blue}] {pos}/{len} ({percent}%) {elapsed_precise}")
12            .unwrap_or_else(|_| ProgressStyle::default_bar())
13            .progress_chars("#>-"),
14    );
15    pb.set_message(message.to_string());
16    pb.enable_steady_tick(Duration::from_millis(100));
17    pb
18}
19
20/// Create a spinner for indeterminate operations
21pub fn create_spinner(message: &str) -> ProgressBar {
22    let pb = ProgressBar::new_spinner();
23    pb.set_style(
24        ProgressStyle::default_spinner()
25            .template("{spinner:.green} {msg}")
26            .unwrap_or_else(|_| ProgressStyle::default_spinner())
27            .tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈ "),
28    );
29    pb.set_message(message.to_string());
30    pb.enable_steady_tick(Duration::from_millis(80));
31    pb
32}
33
34/// Create a progress bar for file transfer operations
35#[allow(dead_code)]
36pub fn create_transfer_bar(total_bytes: u64, file_name: &str) -> ProgressBar {
37    let pb = ProgressBar::new(total_bytes);
38    pb.set_style(
39        ProgressStyle::default_bar()
40            .template("{msg} [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}) {eta}")
41            .unwrap_or_else(|_| ProgressStyle::default_bar())
42            .progress_chars("#>-"),
43    );
44    pb.set_message(format!("Transferring {}", file_name));
45    pb
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_create_progress_bar() {
54        let pb = create_progress_bar(100, "Testing");
55        assert_eq!(pb.length(), Some(100));
56        pb.finish();
57    }
58
59    #[test]
60    fn test_create_spinner() {
61        let pb = create_spinner("Processing");
62        assert!(pb.is_hidden() || !pb.is_finished());
63        pb.finish();
64    }
65
66    #[test]
67    fn test_create_transfer_bar() {
68        let pb = create_transfer_bar(1024, "test.tif");
69        assert_eq!(pb.length(), Some(1024));
70        pb.finish();
71    }
72}