use std::sync::atomic::{AtomicBool, Ordering};
static COLOR_ENABLED: AtomicBool = AtomicBool::new(true);
pub fn init(color: bool) {
COLOR_ENABLED.store(color, Ordering::Relaxed);
}
fn use_color() -> bool {
COLOR_ENABLED.load(Ordering::Relaxed)
}
pub fn success(msg: &str) -> String {
if use_color() {
format!("\x1b[38;5;83m\u{2714}\x1b[0m {msg}")
} else {
format!("[ok] {msg}")
}
}
pub fn fail(msg: &str) -> String {
if use_color() {
format!("\x1b[38;5;196m\u{2718}\x1b[0m {msg}")
} else {
format!("[error] {msg}")
}
}
pub fn step(msg: &str) -> String {
if use_color() {
format!("\x1b[38;5;45m\u{279c}\x1b[0m {msg}")
} else {
format!("[..] {msg}")
}
}
pub fn warn(msg: &str) -> String {
if use_color() {
format!("\x1b[38;5;208m\u{26a0}\x1b[0m {msg}")
} else {
format!("[warn] {msg}")
}
}
pub fn bold(s: &str) -> String {
if use_color() {
format!("\x1b[1m{s}\x1b[0m")
} else {
s.to_string()
}
}
pub fn dim(s: &str) -> String {
if use_color() {
format!("\x1b[2m{s}\x1b[0m")
} else {
s.to_string()
}
}
pub fn color(code: u8, s: &str) -> String {
if use_color() {
format!("\x1b[38;5;{code}m{s}\x1b[0m")
} else {
s.to_string()
}
}
pub fn human_size(bytes: u64) -> String {
if bytes < 1024 {
format!("{bytes} B")
} else if bytes < 1024 * 1024 {
format!("{:.1} KB", bytes as f64 / 1024.0)
} else {
format!("{:.1} MB", bytes as f64 / (1024.0 * 1024.0))
}
}
pub fn spinner(msg: &str) -> indicatif::ProgressBar {
use {
indicatif::{ProgressBar, ProgressStyle},
std::time::Duration,
};
let sp = ProgressBar::new_spinner();
sp.set_style(
ProgressStyle::default_spinner()
.tick_strings(&[
"✦ · · ",
" ✦ · ·",
"· ✦ · ",
" · ✦ ·",
"· · ✦ ",
" · · ✦",
"· · ✦ ",
" · ✦ ·",
"· ✦ · ",
" ✦ · ·",
"✦ · · ",
])
.template(" {spinner:.cyan} {msg}")
.unwrap(),
);
sp.enable_steady_tick(Duration::from_millis(80));
sp.set_message(msg.to_string());
sp
}
pub fn human_duration(d: std::time::Duration) -> String {
let secs = d.as_secs_f64();
if secs < 0.1 {
format!("{:.0}ms", secs * 1000.0)
} else if secs < 60.0 {
format!("{secs:.1}s")
} else {
let mins = secs as u64 / 60;
let rem = secs as u64 % 60;
format!("{mins}m {rem}s")
}
}