diff options
author | Tim Oram <dev@mitmaro.ca> | 2022-12-20 09:35:54 -0330 |
---|---|---|
committer | Tim Oram <dev@mitmaro.ca> | 2022-12-20 10:11:25 -0330 |
commit | fb9a1c025dec1650802fb8952844c31181f104eb (patch) | |
tree | c53f786087efc485eb9e56af52dea7d22225e87a | |
parent | 2feadd31c3c4addc3b564549b735c02bb9c10cb8 (diff) |
Add spin indicator component
-rw-r--r-- | src/core/src/components/mod.rs | 2 | ||||
-rw-r--r-- | src/core/src/components/spin_indicator/mod.rs | 76 |
2 files changed, 78 insertions, 0 deletions
diff --git a/src/core/src/components/mod.rs b/src/core/src/components/mod.rs index 54d5837..21dd23c 100644 --- a/src/core/src/components/mod.rs +++ b/src/core/src/components/mod.rs @@ -4,3 +4,5 @@ pub(crate) mod edit; pub(crate) mod help; pub(crate) mod search_bar; mod shared; +#[allow(dead_code)] +pub(crate) mod spin_indicator; diff --git a/src/core/src/components/spin_indicator/mod.rs b/src/core/src/components/spin_indicator/mod.rs new file mode 100644 index 0000000..e73048b --- /dev/null +++ b/src/core/src/components/spin_indicator/mod.rs @@ -0,0 +1,76 @@ +use std::time::{Duration, Instant}; + +const INDICATOR_CHARACTERS: [&str; 4] = ["-", "\\", "|", "/"]; +const ANIMATE_SPEED: Duration = Duration::from_millis(100); + +pub(crate) struct SpinIndicator { + index: u8, + last_refreshed_at: Instant, +} + +impl SpinIndicator { + pub(crate) fn new() -> Self { + Self { + index: 0, + last_refreshed_at: Instant::now(), + } + } + + pub(crate) fn refresh(&mut self) { + if self.last_refreshed_at.elapsed() >= ANIMATE_SPEED { + self.last_refreshed_at = Instant::now(); + self.index = if self.index == 3 { 0 } else { self.index + 1 } + } + } + + pub(crate) fn indicator(&self) -> String { + format!("({})", INDICATOR_CHARACTERS[self.index as usize]) + } +} +#[cfg(test)] +mod tests { + use std::ops::{Add, Sub}; + + const SAFE_TEST_DURATION: Duration = Duration::from_secs(60); + + use super::*; + + #[test] + fn does_not_advance_if_duration_has_not_elapsed() { + let mut indicator = SpinIndicator::new(); + // this test is unlikely to finish before this elapsed time + indicator.last_refreshed_at = Instant::now().add(SAFE_TEST_DURATION); + assert_eq!(indicator.indicator(), "(-)"); + indicator.refresh(); + assert_eq!(indicator.indicator(), "(-)"); + } + + #[test] + fn does_not_advance_if_duration_has_elapsed() { + let mut indicator = SpinIndicator::new(); + indicator.last_refreshed_at = Instant::now().sub(SAFE_TEST_DURATION); + assert_eq!(indicator.indicator(), "(-)"); + indicator.refresh(); + assert_eq!(indicator.indicator(), "(\\)"); + } + + const INDICATOR_CHARACTERS: [&str; 4] = ["-", "\\", "|", "/"]; + #[test] + fn full_animation() { + let mut indicator = SpinIndicator::new(); + indicator.last_refreshed_at = Instant::now().sub(SAFE_TEST_DURATION); + assert_eq!(indicator.indicator(), "(-)"); + indicator.refresh(); + indicator.last_refreshed_at = indicator.last_refreshed_at.sub(SAFE_TEST_DURATION); + assert_eq!(indicator.indicator(), "(\\)"); + indicator.refresh(); + indicator.last_refreshed_at = indicator.last_refreshed_at.sub(SAFE_TEST_DURATION); + assert_eq!(indicator.indicator(), "(|)"); + indicator.refresh(); + indicator.last_refreshed_at = indicator.last_refreshed_at.sub(SAFE_TEST_DURATION); + assert_eq!(indicator.indicator(), "(/)"); + indicator.refresh(); + indicator.last_refreshed_at = indicator.last_refreshed_at.sub(SAFE_TEST_DURATION); + assert_eq!(indicator.indicator(), "(-)"); + } +} |