tl_cli/ui/
spinner.rs

1use indicatif::{ProgressBar, ProgressStyle};
2use std::time::Duration;
3
4/// A terminal spinner for indicating progress.
5///
6/// Automatically clears itself when dropped (RAII pattern).
7pub struct Spinner {
8    progress_bar: ProgressBar,
9}
10
11impl Spinner {
12    /// Creates and starts a new spinner with the given message.
13    #[allow(clippy::unwrap_used)]
14    pub fn new(message: &str) -> Self {
15        let progress_bar = ProgressBar::new_spinner();
16        // unwrap is safe: template string is a compile-time constant
17        progress_bar.set_style(
18            ProgressStyle::default_spinner()
19                .tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
20                .template("{spinner} {msg}")
21                .unwrap(),
22        );
23        progress_bar.set_message(message.to_string());
24        progress_bar.enable_steady_tick(Duration::from_millis(80));
25
26        Self { progress_bar }
27    }
28
29    /// Stops the spinner and clears it from the terminal.
30    pub fn stop(&self) {
31        self.progress_bar.finish_and_clear();
32    }
33}
34
35impl Drop for Spinner {
36    fn drop(&mut self) {
37        self.progress_bar.finish_and_clear();
38    }
39}