use std::io::{stdout, Write};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::thread;
use std::time::Duration;
use crossterm::{
ExecutableCommand,
cursor,
terminal::{self, Clear, ClearType},
};
fn start_delayed_spinner(is_searching: Arc<AtomicBool>, delay: Duration) {
let spinner_frames = vec!["|", "/", "-", "\\"];
let mut stdout = stdout();
let mut frame_idx = 0;
thread::spawn(move || {
// Sleep for the delay duration before starting the spinner
thread::sleep(delay);
// Only start the spinner if the search is still ongoing
if is_searching.load(Ordering::Relaxed) {
stdout.execute(Clear(ClearType::CurrentLine)).unwrap();
while is_searching.load(Ordering::Relaxed) {
// Move the cursor to the beginning of the line
stdout.execute(cursor::MoveToColumn(0)).unwrap();
// Print the spinner frame
let frame = spinner_frames[frame_idx % spinner_frames.len()];
print!("Searching... {}", frame);
stdout.flush().unwrap();
// Sleep for a short while to create the animation effect
thread::sleep(Duration::from_millis(100));
// Advance to the next frame
frame_idx += 1;
}
// Clear spinner when done
stdout.execute(Clear(ClearType::CurrentLine)).unwrap();
println!("Search complete!");
}
});
}
fn main() {
let is_searching = Arc::new(AtomicBool::new(true));
let delay = Duration::from_secs(1); // Delay before showing spinner
// Start the delayed spinner animation
let spinner_handle = {
let is_searching = Arc::clone(&is_searching);
start_delayed_spinner(is_searching, delay);
};
// Simulate a search routine (you can replace this with your actual search code)
thread::sleep(Duration::from_secs(3)); // Simulating a 3-second search
// Stop the spinner
is_searching.store(false, Ordering::Relaxed);
// Allow the spinner thread to finish
thread::sleep(Duration::from_millis(500)); // Give time for spinner to clear line
}
Sample implementation: