alopex-cli 0.6.0

Command-line interface for Alopex DB
use std::time::Duration;

use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};

use crate::batch::BatchMode;

pub struct ProgressIndicator {
    bar: Option<ProgressBar>,
    finished: bool,
}

impl ProgressIndicator {
    pub fn new(
        batch_mode: &BatchMode,
        explicit_progress: bool,
        quiet: bool,
        message: impl Into<String>,
    ) -> Self {
        if quiet || !batch_mode.should_show_progress(explicit_progress) {
            return Self {
                bar: None,
                finished: false,
            };
        }

        let bar = ProgressBar::new_spinner();
        bar.set_draw_target(ProgressDrawTarget::stderr());
        let style = ProgressStyle::with_template("{spinner} {msg}")
            .unwrap()
            .tick_strings(&["-", "\\", "|", "/"]);
        bar.set_style(style);
        bar.set_message(message.into());
        bar.enable_steady_tick(Duration::from_millis(120));

        Self {
            bar: Some(bar),
            finished: false,
        }
    }

    pub fn finish_with_message(&mut self, message: impl Into<String>) {
        if let Some(bar) = &self.bar {
            bar.finish_with_message(message.into());
            self.finished = true;
        }
    }

    pub fn finish_and_clear(&mut self) {
        if let Some(bar) = &self.bar {
            bar.finish_and_clear();
            self.finished = true;
        }
    }
}

impl Drop for ProgressIndicator {
    fn drop(&mut self) {
        if self.bar.is_some() && !self.finished {
            self.finish_and_clear();
        }
    }
}