multi_progressbar/bar/
classic.rs

1use crate::{ProgressBar, TaskProgress};
2
3/// ClassicProgressBar is a classic progress bar, using `[=> ]` to show progress.
4pub struct ClassicProgressBar<T: TaskProgress> {
5    _phantom: std::marker::PhantomData<T>,
6}
7
8impl<T> ClassicProgressBar<T>
9where
10    T: TaskProgress,
11{
12    /// creates a new ClassicProgressBar.
13    pub fn new() -> Self {
14        ClassicProgressBar {
15            _phantom: std::marker::PhantomData,
16        }
17    }
18}
19
20impl<T> ProgressBar for ClassicProgressBar<T>
21where
22    T: TaskProgress,
23{
24    type Task = T;
25    fn format_line(&self, progress: &T, width: usize) -> String {
26        let (before, after) = (progress.before(), progress.after());
27        let (current, total) = progress.progress();
28
29        if total == 0 {
30            return " ".repeat(width);
31        }
32
33        let before_len = before.as_ref().map(|s| s.len()).unwrap_or(0);
34        let after_len = after.as_ref().map(|s| s.len()).unwrap_or(0);
35
36        // check if we have enough space to show progress bar
37        if before_len + after_len + 2 > width {
38            return " ".repeat(width);
39        }
40
41        let bar_width = width - before_len - after_len - 2;
42        let bar_progress = (current as f64 / total as f64 * bar_width as f64) as usize;
43
44        let mut bar = String::new();
45        bar.push_str(&before.unwrap_or_default());
46        bar.push('[');
47        bar.push_str(&"=".repeat(bar_progress));
48        bar.push_str(&" ".repeat(bar_width - bar_progress));
49        bar.push(']');
50        bar.push_str(&after.unwrap_or_default());
51        bar
52    }
53}