ahiru-tpm 0.5.0

Drop-in replacement for the famous Tmux Plugin Manager (TPM), written in Rust. 🦆
Documentation
use std::time::Duration;

use anyhow::{Context, Result};
use colored::Colorize;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};

pub struct ProgressStatus {
    multi_progress: MultiProgress,
}

impl Default for ProgressStatus {
    fn default() -> Self {
        Self::new()
    }
}

impl ProgressStatus {
    pub fn new() -> ProgressStatus {
        let multi_progress = MultiProgress::new();

        ProgressStatus { multi_progress }
    }

    pub fn add_task(&self, task_name: &str, initial_status: &str) -> Result<ProgressTask> {
        let progress_bar = self.multi_progress.add(ProgressBar::new_spinner());
        let progress_task = ProgressTask::new(progress_bar, task_name.to_string());
        progress_task.set_status(initial_status)?;
        Ok(progress_task)
    }
}

pub struct ProgressTask {
    task_name: String,
    progress_bar: ProgressBar,
}

impl ProgressTask {
    pub fn new(progress_bar: ProgressBar, task_name: String) -> ProgressTask {
        ProgressTask {
            task_name,
            progress_bar,
        }
    }

    pub fn set_status(&self, status: &str) -> Result<()> {
        self.progress_bar
            .set_message(format!("{:<64} {}", self.task_name, status.bold().cyan()));
        self.progress_bar
            .enable_steady_tick(Duration::from_millis(100));
        self.progress_bar.set_style(
            ProgressStyle::with_template("{spinner:.cyan} {msg}")
                .context("Failed to set progress style")?,
        );
        Ok(())
    }

    pub fn set_success(&self, status: &str) -> Result<()> {
        self.progress_bar.set_style(
            ProgressStyle::with_template(&format!("{} {}", "✔".bold().green(), "{msg}"))
                .context("Failed to set progress style")?,
        );
        self.progress_bar.finish_with_message(format!(
            "{:<64} {}",
            self.task_name,
            status.bold().green()
        ));
        Ok(())
    }

    pub fn set_failed(&self, status: &str) -> Result<()> {
        self.progress_bar.set_style(
            ProgressStyle::with_template(&format!("{} {}", "✘".bold().red(), "{msg}"))
                .context("Failed to set progress style")?,
        );
        self.progress_bar.finish_with_message(format!(
            "{:<64} {}",
            self.task_name,
            status.bold().red()
        ));
        Ok(())
    }
}