use std::{
io::Write,
sync::{atomic::AtomicBool, Arc},
};
use crate::terminal::color::Color;
const FRAMES: [char; 10] = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
#[derive(Debug, Default)]
pub struct Spinner(Arc<AtomicBool>);
impl Spinner {
pub fn show_cursor() {
let mut std = std::io::stdout().lock();
std.write_all(b"\x1B[?25h").ok();
std.flush().ok();
}
fn hide_cursor() {
let mut std = std::io::stdout().lock();
std.write_all(b"\x1B[?25l").ok();
std.flush().ok();
}
async fn spin(run: Arc<AtomicBool>) {
while run.load(std::sync::atomic::Ordering::SeqCst) {
for i in FRAMES {
print!("{c}{i}{r} scanning ", c = Color::Red, r = Color::Reset);
std::io::stdout().flush().ok();
print!("\r");
tokio::time::sleep(std::time::Duration::from_millis(75)).await;
}
}
}
pub fn start() -> Self {
let spinner = Self(Arc::new(AtomicBool::new(true)));
Self::hide_cursor();
tokio::spawn(Self::spin(Arc::clone(&spinner.0)));
spinner
}
pub fn stop(&self) {
self.0.store(false, std::sync::atomic::Ordering::SeqCst);
Self::show_cursor();
}
}