Skip to main content

kget/
progress.rs

1//! Progress bar utilities for download visualization.
2//!
3//! This module provides a customizable progress bar for tracking downloads
4//! in the terminal.
5//!
6//! # Example
7//!
8//! ```rust,no_run
9//! use kget::create_progress_bar;
10//!
11//! // Create a progress bar for a 100MB file
12//! let pb = create_progress_bar(false, "Downloading file.zip".into(), Some(100_000_000), false);
13//! pb.set_position(50_000_000); // 50% complete
14//! pb.finish_with_message("Download complete!");
15//! ```
16
17use indicatif::{ProgressBar, ProgressStyle};
18
19/// Create a progress bar for download tracking.
20///
21/// # Arguments
22///
23/// * `quiet_mode` - If true, returns a hidden progress bar (no output)
24/// * `msg` - Message to display above the progress bar
25/// * `length` - Total size in bytes (None for indeterminate spinner)
26/// * `is_parallel` - If true, shows chunk information for parallel downloads
27///
28/// # Returns
29///
30/// A configured [`ProgressBar`] ready for use.
31///
32/// # Example
33///
34/// ```rust,no_run
35/// use kget::create_progress_bar;
36///
37/// // Determinate progress bar
38/// let pb = create_progress_bar(false, "file.zip".into(), Some(1000), false);
39///
40/// // Indeterminate spinner (unknown size)
41/// let spinner = create_progress_bar(false, "Connecting...".into(), None, false);
42///
43/// // Parallel download progress
44/// let parallel = create_progress_bar(false, "file.iso".into(), Some(4_000_000_000), true);
45/// ```
46pub fn create_progress_bar(
47    quiet_mode: bool,
48    msg: String,
49    length: Option<u64>,
50    is_parallel: bool,
51) -> ProgressBar {
52    let bar = if quiet_mode {
53        ProgressBar::hidden()
54    } else {
55        match length {
56            Some(len) => ProgressBar::new(len),
57            None => ProgressBar::new_spinner(),
58        }
59    };
60
61    bar.set_message(msg);
62
63    if let Some(_) = length {
64        let template = if is_parallel {
65            "{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({percent}%) eta: {eta} speed: {binary_bytes_per_sec}\nChunks: {chunks} active"
66        } else {
67            "{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({percent}%) eta: {eta} speed: {binary_bytes_per_sec}"
68        };
69
70        bar.set_style(
71            ProgressStyle::default_bar()
72                .template(template)
73                .unwrap()
74                .progress_chars("=>-"),
75        );
76    } else {
77        bar.set_style(
78            ProgressStyle::default_spinner()
79                .template("{spinner:.green} {msg} {elapsed}")
80                .unwrap(),
81        );
82    }
83
84    bar
85}