use console::style;
use indicatif::{ProgressBar, ProgressStyle};
use std::time::Duration;
pub struct Spinner {
bar: ProgressBar,
}
impl Spinner {
pub fn new(message: &str) -> Self {
let bar = ProgressBar::new_spinner();
bar.set_style(
ProgressStyle::default_spinner()
.tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
.template("{spinner:.cyan} {msg}")
.expect("valid template"),
);
bar.set_message(message.to_string());
bar.enable_steady_tick(Duration::from_millis(80));
Self { bar }
}
pub fn set_message(&self, message: &str) {
self.bar.set_message(message.to_string());
}
pub fn finish_success(&self, message: &str) {
self.bar.finish_and_clear();
eprintln!("{} {}", style("[OK]").green().bold(), message);
}
pub fn finish_warning(&self, message: &str) {
self.bar.finish_and_clear();
eprintln!("{} {}", style("[!]").yellow().bold(), message);
}
pub fn finish_error(&self, message: &str) {
self.bar.finish_and_clear();
eprintln!("{} {}", style("[ERR]").red().bold(), message);
}
pub fn finish_clear(&self) {
self.bar.finish_and_clear();
}
}
pub fn success(message: &str) {
eprintln!("{} {}", style("[OK]").green().bold(), message);
}
pub fn info(message: &str) {
eprintln!("{} {}", style("[i]").blue().bold(), message);
}
pub fn warning(message: &str) {
eprintln!("{} {}", style("[!]").yellow().bold(), message);
}
pub fn error(message: &str) {
eprintln!("{} {}", style("[ERR]").red().bold(), message);
}
pub fn format_duration(duration: Duration) -> String {
let secs = duration.as_secs_f64();
if secs < 1.0 {
format!("{:.0}ms", secs * 1000.0)
} else if secs < 60.0 {
format!("{:.2}s", secs)
} else {
let mins = secs / 60.0;
format!("{:.1}m", mins)
}
}
pub fn format_count(count: usize, singular: &str, plural: &str) -> String {
if count == 1 {
format!("{} {}", count, singular)
} else {
format!("{} {}", count, plural)
}
}