From 88183858b137c03c727abc3f4937f106a22ace17 Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Fri, 10 Jul 2020 11:28:06 -0700 Subject: Refactor the CLI spinner --- src/term.rs | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/term.rs b/src/term.rs index 038c92b..77f5457 100644 --- a/src/term.rs +++ b/src/term.rs @@ -7,7 +7,7 @@ use std::io::{stderr, Write}; use termimad::{CompoundStyle, MadSkin}; use tokio::sync::{ oneshot, - oneshot::{error::TryRecvError, Sender}, + oneshot::{error::TryRecvError, Sender, Receiver}, }; use tokio::task::JoinHandle; use tokio::time; @@ -32,6 +32,11 @@ impl Default for Term { } } +struct Spinner { + tx: Sender<()>, + handle: JoinHandle> +} + impl Term { pub fn new() -> Self { let mut skin = MadSkin::default(); @@ -101,23 +106,36 @@ impl Term { F: Future, { // Start spinner - let (tx, spinner_handle) = Self::spinner(); + let spinner = Spinner::new(); let result = future.await; // Stop spinner - tx.send(()).ok(); - spinner_handle.await??; + spinner.stop().await?; Ok(result) } +} + +impl Spinner { + /// Start a CLI spinner on the current cursor line. To stop it, call `stop` on the returned + /// `Spinner`. + pub fn new() -> Self { + let (tx, rx) = oneshot::channel(); + let handle = tokio::spawn(Self::spin(rx)); + Spinner {tx, handle} + } + + /// Stop the spinner. This requires a bit of cleanup, and so should be `await`ed before doing + /// any other i/o. + pub async fn stop(self) -> Result<()> { + self.tx.send(()).ok(); + self.handle.await??; + Ok(()) + } - /// Start a CLI spinner on the current cursor line. To stop it, call `send` on the `Sender`. To - /// wait until it's done cleaning up it's current action (which is very important), await it's - /// `JoinHandle`. - fn spinner() -> (Sender<()>, JoinHandle>) { - let (tx, mut rx) = oneshot::channel(); - let spinner_handle = tokio::spawn(async move { + /// Spin until receiver finds unit + async fn spin(mut rx: Receiver<()>) -> Result<()> { let mut dots = LOADING_SPINNER_DOTS.iter().cycle(); terminal::enable_raw_mode()?; execute!( @@ -144,8 +162,6 @@ impl Term { )?; terminal::disable_raw_mode()?; Ok(()) - }); - (tx, spinner_handle) } } -- cgit v1.2.3