use std::time::Duration;
use console::style;
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
pub fn header(title: &str) {
eprintln!("\n{}", style(title).bold().cyan());
}
pub fn ok(msg: &str) {
eprintln!("{} {msg}", style("✓").green().bold());
}
pub fn warn(msg: &str) {
eprintln!("{} {msg}", style("!").yellow().bold());
}
pub fn err(msg: &str) {
eprintln!("{} {msg}", style("✗").red().bold());
}
pub fn step(msg: &str) {
eprintln!("{} {msg}", style("→").cyan().bold());
}
pub fn note(msg: &str) {
eprintln!(" {}", style(msg).dim());
}
pub fn field(label: &str, value: &str) {
eprintln!(" {} {value}", style(format!("{label}:")).dim());
}
pub fn spinner(msg: &str) -> ProgressBar {
let pb = ProgressBar::with_draw_target(None, ProgressDrawTarget::stderr());
pb.set_style(
ProgressStyle::with_template("{spinner:.cyan} {msg} {elapsed:.dim}")
.unwrap_or_else(|_| ProgressStyle::default_spinner()),
);
pb.set_message(msg.to_string());
pb.enable_steady_tick(Duration::from_millis(90));
pb
}
pub fn table(headers: &[&str]) -> comfy_table::Table {
let mut t = comfy_table::Table::new();
t.load_preset(comfy_table::presets::UTF8_FULL)
.set_content_arrangement(comfy_table::ContentArrangement::Dynamic)
.set_header(headers.to_vec());
t
}
pub fn right_align(t: &mut comfy_table::Table, cols: &[usize]) {
for &c in cols {
if let Some(col) = t.column_mut(c) {
col.set_cell_alignment(comfy_table::CellAlignment::Right);
}
}
}
pub fn progress(len: u64, msg: &str) -> ProgressBar {
let pb = ProgressBar::with_draw_target(Some(len), ProgressDrawTarget::stderr());
pb.set_style(
ProgressStyle::with_template(
"{spinner:.cyan} [{elapsed_precise}] [{bar:32.cyan/blue}] {pos}/{len} {msg} {eta:.dim}",
)
.unwrap_or_else(|_| ProgressStyle::default_bar())
.progress_chars("=>-"),
);
pb.set_message(msg.to_string());
pb.enable_steady_tick(Duration::from_millis(90));
pb
}