Skip to main content

fitscube_rs/
progress.rs

1//! Progress bars and spinners for long-running CLI work.
2//!
3//! Mirrors the helpers in the sibling `convolve-rs` tool. These are opt-in: the
4//! library only builds them when a caller sets `progress` on its options
5//! (the CLI does; the Python bindings leave it off so importing the module
6//! stays quiet). The work loops in [`crate::combine`] drive them.
7use std::time::Duration;
8
9use indicatif::{ProgressBar, ProgressStyle};
10
11/// A determinate bar for `total` items (e.g. one tick per written channel).
12pub fn progress_bar(total: u64) -> ProgressBar {
13    let pb = ProgressBar::new(total);
14    pb.set_style(
15        ProgressStyle::default_bar()
16            .template("{spinner:.green} [{elapsed}] [{bar:40.cyan/blue}] {pos}/{len} {msg}")
17            .unwrap()
18            .progress_chars("=>-"),
19    );
20    // Steady tick animates the `{spinner}` even when `pos` is not advancing, so
21    // idle-but-busy phases (e.g. the parallel readers warming up before the
22    // first plane lands) still show live activity rather than a frozen bar.
23    pb.enable_steady_tick(Duration::from_millis(100));
24    pb
25}
26
27/// An indeterminate spinner for blocking phases with no item count (e.g.
28/// solving for a common bounding box). The caller clears it via
29/// `finish_and_clear` when the work completes.
30pub fn spinner(msg: impl Into<String>) -> ProgressBar {
31    let pb = ProgressBar::new_spinner();
32    pb.set_style(
33        ProgressStyle::default_spinner()
34            .template("{spinner:.green} [{elapsed}] {msg}")
35            .unwrap(),
36    );
37    pb.set_message(msg.into());
38    pb.enable_steady_tick(Duration::from_millis(100));
39    pb
40}