@@ -5,15 +5,55 @@ use crate::core::{Pane, grapheme::StyledGraphemes, render::SharedRenderer};
55pub mod frame;
66use frame:: Frame ;
77
8+ /// Trait to define the state of the spinner.
89pub trait State {
910 fn is_idle ( & self ) -> impl Future < Output = bool > + Send ;
1011}
1112
13+ /// A spinner that can be used to indicate loading or processing states.
14+ #[ derive( Clone , Debug ) ]
15+ pub struct Spinner {
16+ /// The frames of the spinner, which are the characters that will be displayed in a rotating manner.
17+ pub frames : Frame ,
18+ /// A suffix that will be displayed alongside the spinner.
19+ pub suffix : String ,
20+ /// The duration between frame updates.
21+ pub duration : Duration ,
22+ }
23+
24+ impl Default for Spinner {
25+ fn default ( ) -> Self {
26+ Self {
27+ frames : frame:: DOTS . clone ( ) ,
28+ suffix : String :: new ( ) ,
29+ duration : Duration :: from_millis ( 100 ) ,
30+ }
31+ }
32+ }
33+
34+ impl Spinner {
35+ /// Set frames for the spinner.
36+ pub fn frames ( mut self , frames : Frame ) -> Self {
37+ self . frames = frames;
38+ self
39+ }
40+
41+ /// Set a suffix for the spinner.
42+ pub fn suffix ( mut self , suffix : impl Into < String > ) -> Self {
43+ self . suffix = suffix. into ( ) ;
44+ self
45+ }
46+
47+ /// Set the duration between frame updates.
48+ pub fn duration ( mut self , duration : Duration ) -> Self {
49+ self . duration = duration;
50+ self
51+ }
52+ }
53+
1254/// Spawn a background task that shows a spinner while the state is active.
1355pub async fn run < S , I > (
14- spinner : Frame ,
15- suffix : & str ,
16- duration : Duration ,
56+ spinner : & Spinner ,
1757 state : S ,
1858 index : I ,
1959 renderer : SharedRenderer < I > ,
@@ -23,21 +63,21 @@ where
2363 I : Clone + Ord + Send ,
2464{
2565 let mut frame_index = 0 ;
26- let mut interval = tokio:: time:: interval ( duration) ;
66+ let mut interval = tokio:: time:: interval ( spinner . duration ) ;
2767
2868 loop {
2969 interval. tick ( ) . await ;
3070
3171 if !state. is_idle ( ) . await {
32- frame_index = ( frame_index + 1 ) % spinner. len ( ) ;
72+ frame_index = ( frame_index + 1 ) % spinner. frames . len ( ) ;
3373
3474 renderer
3575 . update ( [ (
3676 index. clone ( ) ,
3777 Pane :: new (
3878 vec ! [ StyledGraphemes :: from( format!(
3979 "{} {}" ,
40- spinner[ frame_index] , suffix
80+ spinner. frames [ frame_index] , spinner . suffix
4181 ) ) ] ,
4282 0 ,
4383 ) ,
0 commit comments