parsli 0.1.0

Parallel status lines for Rust
Documentation
use std::sync::Arc;
use std::time::Duration;
use console::style;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};

/// The state that a bar should be updated to
#[derive(PartialEq, Clone)]
pub(crate) enum LineStatus { Idle, Busy }


/// A wrapper for a progress bar providing convenient methods
#[derive(Debug, Clone)]
pub struct Line {
    /// The inner progress bar
    bar: ProgressBar,
}


impl Line {
    /// Creates a new stat bar and adds it to the multi progress display
    pub(crate) fn new(progress: Arc<MultiProgress>) -> Self {
        Self { bar: progress.add(ProgressBar::new(0)) }
    }

    /// Print line above status bar
    pub fn println(&self, message: String) {
        self.bar.println(message);
    }

    /// Updates the highlighted text in front of the displayed message
    pub(crate) fn update_prefix(&self, prefix: String) {
        self.bar.set_prefix(prefix);
    }

    /// Updates the displayed message
    pub fn update_message(&self, message: String) {
        self.update_status_and_message(LineStatus::Busy, message)
    }

    /// Updates the status and the displayed message
    pub(crate) fn update_status_and_message(&self, status: LineStatus, message: String) {
        // Update ticking
        if status == LineStatus::Busy {
            self.bar.enable_steady_tick(Duration::from_millis(1000 / 30));
        } else {
            self.bar.disable_steady_tick()
        }

        // Update style
        let mut progress_style = ProgressStyle::default_spinner().template("{prefix:.bold.dim} {wide_msg}").unwrap();
        if status == LineStatus::Busy {
            progress_style = progress_style
                .tick_chars("⠈⠐⠠⢀⡀⠄⠂⠁ ")
                .template("{prefix:.bold.dim} {spinner:.yellow} {wide_msg} {binary_bytes_per_sec}").unwrap();
        }
        self.bar.set_style(progress_style);

        // Compose message
        let message = format!(
            "{}{}",
            match status {
                LineStatus::Idle => style("- ").yellow(),
                LineStatus::Busy => style("").white(),
            },
            message
        );
        self.bar.set_message(message);
    }

    /// Updates the position of the stat bar, currently used for download speed
    pub(crate) fn update_position(&self, position: usize) {
        self.bar.set_position(position as u64);
    }

    /// Temporarily suspend
    pub(crate) fn suspend<F: FnOnce() -> R, R>(&self, f: F) -> R {
        self.bar.suspend(f)
    }
}