use std::time::Instant;
use console::{style, Emoji};
use indicatif::{HumanDuration, ProgressBar, ProgressStyle};
pub static SPARKLE: Emoji<'_, '_> = Emoji("✨ ", ":-)");
static PROGRESS_BAR_TEMPLATE: &str =
"{spinner:.green} [{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {per_sec} ({eta})";
pub struct Logger {
current: usize,
total: usize,
quiet: bool,
execution_start: Instant,
progress_bar: Option<ProgressBar>,
}
impl Logger {
pub fn new(total: usize, quiet: bool) -> Self {
Self {
current: 0,
total,
quiet,
execution_start: Instant::now(),
progress_bar: None,
}
}
pub fn message(&mut self, text: &str) {
if self.current < self.total {
self.current += 1;
if !self.quiet {
println!(
"{} {}",
style(format!("[{}/{}]", self.current, self.total))
.bold()
.dim(),
text
);
}
} else {
eprintln!("Warning: Current step exceeds total steps.");
}
}
pub fn increment_progress(&self, done_lines: usize) {
if let Some(ref pb) = self.progress_bar {
pb.inc(done_lines as u64)
}
}
pub fn set_progress_bar(&mut self, size: usize) {
if !self.quiet {
let progress_bar_style = ProgressStyle::with_template(PROGRESS_BAR_TEMPLATE)
.expect("Failed to parse a progress bar template")
.progress_chars("##-");
let progress_bar = ProgressBar::new(size as u64);
progress_bar.set_style(progress_bar_style);
self.progress_bar = Some(progress_bar);
}
}
pub fn final_message(&self) {
if self.progress_bar.is_some() {
println!(
"{} Done in {}",
SPARKLE,
HumanDuration(self.execution_start.elapsed())
)
}
}
}