parsli/
line.rs

1use std::sync::Arc;
2use std::time::Duration;
3use console::style;
4use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
5
6/// The state that a bar should be updated to
7#[derive(PartialEq, Clone)]
8pub(crate) enum LineStatus { Idle, Busy }
9
10
11/// A wrapper for a progress bar providing convenient methods
12#[derive(Debug, Clone)]
13pub struct Line {
14    /// The inner progress bar
15    bar: ProgressBar,
16}
17
18
19impl Line {
20    /// Creates a new stat bar and adds it to the multi progress display
21    pub(crate) fn new(progress: Arc<MultiProgress>) -> Self {
22        Self { bar: progress.add(ProgressBar::new(0)) }
23    }
24
25    /// Print line above status bar
26    pub fn println(&self, message: String) {
27        self.bar.println(message);
28    }
29
30    /// Updates the highlighted text in front of the displayed message
31    pub(crate) fn update_prefix(&self, prefix: String) {
32        self.bar.set_prefix(prefix);
33    }
34
35    /// Updates the displayed message
36    pub fn update_message(&self, message: String) {
37        self.update_status_and_message(LineStatus::Busy, message)
38    }
39
40    /// Updates the status and the displayed message
41    pub(crate) fn update_status_and_message(&self, status: LineStatus, message: String) {
42        // Update ticking
43        if status == LineStatus::Busy {
44            self.bar.enable_steady_tick(Duration::from_millis(1000 / 30));
45        } else {
46            self.bar.disable_steady_tick()
47        }
48
49        // Update style
50        let mut progress_style = ProgressStyle::default_spinner().template("{prefix:.bold.dim} {wide_msg}").unwrap();
51        if status == LineStatus::Busy {
52            progress_style = progress_style
53                .tick_chars("⠈⠐⠠⢀⡀⠄⠂⠁ ")
54                .template("{prefix:.bold.dim} {spinner:.yellow} {wide_msg} {binary_bytes_per_sec}").unwrap();
55        }
56        self.bar.set_style(progress_style);
57
58        // Compose message
59        let message = format!(
60            "{}{}",
61            match status {
62                LineStatus::Idle => style("- ").yellow(),
63                LineStatus::Busy => style("").white(),
64            },
65            message
66        );
67        self.bar.set_message(message);
68    }
69
70    /// Updates the position of the stat bar, currently used for download speed
71    pub(crate) fn update_position(&self, position: usize) {
72        self.bar.set_position(position as u64);
73    }
74
75    /// Temporarily suspend
76    pub(crate) fn suspend<F: FnOnce() -> R, R>(&self, f: F) -> R {
77        self.bar.suspend(f)
78    }
79}