use std::io::{self, Write};
use std::sync::atomic::{AtomicU8, Ordering};
use std::thread;
use std::time::Duration;
const BAR_WIDTH: usize = 40;
const ANIMATE_MS: u64 = 35;
static CURRENT_PCT: AtomicU8 = AtomicU8::new(0);
pub fn progress_line(percent: u8, step: &str) -> String {
let filled = (percent as usize * BAR_WIDTH) / 100;
let empty = BAR_WIDTH.saturating_sub(filled);
let bar: String = "=".repeat(filled) + &"-".repeat(empty);
format!("{} %{} {}", bar, percent, step)
}
pub fn show(percent: u8, step: &str) {
let line = progress_line(percent, step);
print!("\r{:<80}", line);
io::stdout().flush().unwrap();
}
pub fn animate_to(target: u8, step: &str) -> thread::JoinHandle<()> {
let step = step.to_string();
thread::spawn(move || {
loop {
let current = CURRENT_PCT.load(Ordering::Relaxed);
if current >= target {
break;
}
let next = current.saturating_add(1).min(target);
CURRENT_PCT.store(next, Ordering::Relaxed);
show(next, &step);
thread::sleep(Duration::from_millis(ANIMATE_MS));
}
})
}
pub fn wait_animate(handle: thread::JoinHandle<()>) {
let _ = handle.join();
}
pub fn finish() {
println!();
CURRENT_PCT.store(0, Ordering::Relaxed);
}