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}