From b3162a72b50f88d78ca3d57c1f8b3421cecfe2b4 Mon Sep 17 00:00:00 2001 From: sigoden Date: Sun, 21 Apr 2024 06:52:22 +0800 Subject: refactor: shell execution with spinner and select prompt (#425) --- src/utils/spinner.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/utils/spinner.rs (limited to 'src/utils/spinner.rs') diff --git a/src/utils/spinner.rs b/src/utils/spinner.rs new file mode 100644 index 0000000..c684901 --- /dev/null +++ b/src/utils/spinner.rs @@ -0,0 +1,52 @@ +use anyhow::Result; +use crossterm::{cursor, queue, style, terminal}; +use std::io::{Stdout, Write}; + +pub struct Spinner { + index: usize, + message: String, + stopped: bool, +} + +impl Spinner { + const DATA: [&'static str; 10] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; + + pub fn new(message: &str) -> Self { + Spinner { + index: 0, + message: message.to_string(), + stopped: false, + } + } + + pub fn step(&mut self, writer: &mut Stdout) -> Result<()> { + if self.stopped { + return Ok(()); + } + let frame = Self::DATA[self.index % Self::DATA.len()]; + let dots = ".".repeat((self.index / 5) % 4); + let line = format!("{frame}{}{:<3}", self.message, dots); + queue!(writer, cursor::MoveToColumn(0), style::Print(line),)?; + if self.index == 0 { + queue!(writer, cursor::Hide)?; + } + writer.flush()?; + self.index += 1; + Ok(()) + } + + pub fn stop(&mut self, writer: &mut Stdout) -> Result<()> { + if self.stopped { + return Ok(()); + } + self.stopped = true; + queue!( + writer, + cursor::MoveToColumn(0), + terminal::Clear(terminal::ClearType::FromCursorDown), + cursor::Show + )?; + writer.flush()?; + Ok(()) + } +} -- cgit v1.2.3