use std::io::IsTerminal;
use indicatif::{
ProgressBar,
ProgressStyle,
};
pub struct ProgressLogger {
quiet: bool,
progress: Option<ProgressBar>,
}
impl ProgressLogger {
pub fn new(quiet: bool) -> Self {
Self {
quiet,
progress: None,
}
}
#[allow(clippy::disallowed_methods)] pub fn should_show_progress(&self) -> bool {
if self.quiet {
return false;
}
match std::env::var("CARGO_TERM_PROGRESS_WHEN")
.as_deref()
.unwrap_or("auto")
{
"never" => false,
"always" => true,
"auto" => {
std::io::stdout().is_terminal()
}
_ => {
std::io::stdout().is_terminal()
}
}
}
pub fn set_progress(&mut self, total: u64) {
if !self.should_show_progress() {
return;
}
let pb = ProgressBar::new(total);
pb.set_style(
ProgressStyle::default_bar()
.template("{spinner:.green} {msg} [{bar:40.cyan/blue}] {pos}/{len}")
.unwrap()
.progress_chars("#>-"),
);
self.progress = Some(pb);
}
pub fn set_message(&self, msg: &str) {
if let Some(pb) = &self.progress {
pb.set_message(msg.to_string());
}
}
pub fn inc(&self) {
if let Some(pb) = &self.progress {
pb.inc(1);
}
}
pub fn println(&mut self, msg: &str) {
if !self.quiet {
if let Some(pb) = &self.progress {
pb.suspend(|| {
println!("{}", msg);
});
} else {
println!("{}", msg);
}
}
}
pub fn status(&mut self, action: &str, target: &str) {
if !self.quiet {
if let Some(pb) = &self.progress {
pb.suspend(|| {
println!(" {} {}", action, target);
});
} else {
println!(" {} {}", action, target);
}
}
}
pub fn finish(&mut self) {
if let Some(pb) = self.progress.take() {
pb.finish_and_clear();
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_progress_logger_new() {
let logger = ProgressLogger::new(false);
assert!(!logger.quiet);
assert!(logger.progress.is_none());
}
#[test]
fn test_progress_logger_quiet() {
let logger = ProgressLogger::new(true);
assert!(logger.quiet);
assert!(!logger.should_show_progress());
}
#[test]
fn test_progress_logger_set_progress() {
let mut logger = ProgressLogger::new(false);
logger.set_progress(10);
}
#[test]
fn test_progress_logger_inc() {
let mut logger = ProgressLogger::new(false);
logger.set_progress(10);
logger.inc();
}
#[test]
fn test_progress_logger_finish() {
let mut logger = ProgressLogger::new(false);
logger.set_progress(10);
logger.finish();
assert!(logger.progress.is_none());
}
}