use std::io::IsTerminal;
use console::style;
use indicatif::{ProgressBar, ProgressStyle};
pub(crate) struct Progress {
bar: Option<ProgressBar>,
}
impl Default for Progress {
fn default() -> Self {
Self::new(false)
}
}
impl Progress {
pub fn new(verbose: bool) -> Self {
let is_tty = std::io::stderr().is_terminal();
Self {
bar: if is_tty && !verbose {
let pb = ProgressBar::new_spinner();
pb.set_style(
ProgressStyle::default_spinner()
.template("{spinner:.cyan} {msg}")
.expect("valid template")
.tick_chars("⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"),
);
pb.enable_steady_tick(std::time::Duration::from_millis(80));
Some(pb)
} else {
None
},
}
}
pub fn phase(&self, msg: &str) {
if let Some(ref bar) = self.bar {
bar.set_message(msg.to_string());
} else {
eprintln!("{} {}", style("→").cyan(), msg);
}
}
pub fn info(&self, msg: &str) {
if let Some(ref bar) = self.bar {
bar.suspend(|| {
eprintln!("{} {}", style("info:").cyan(), msg);
});
} else {
eprintln!("{} {}", style("info:").cyan(), msg);
}
}
pub fn warning(&self, msg: &str) {
if let Some(ref bar) = self.bar {
bar.suspend(|| {
eprintln!("{} {}", style("warning:").yellow().bold(), msg);
});
} else {
eprintln!("{} {}", style("warning:").yellow().bold(), msg);
}
}
pub fn finish(&self) {
if let Some(ref bar) = self.bar {
bar.finish_and_clear();
}
}
pub fn take_bar(&mut self) -> Option<ProgressBar> {
self.bar.take()
}
}
impl Drop for Progress {
fn drop(&mut self) {
if let Some(ref bar) = self.bar {
bar.finish_and_clear();
}
}
}