use std::sync::LazyLock;
use std::time::Instant;
use crate::ui::config::UI;
type Milliseconds = u64;
static EPOCH: LazyLock<Instant> = LazyLock::new(Instant::now);
pub fn busy_frame() -> &'static str {
frame_at(Milliseconds::try_from(EPOCH.elapsed().as_millis()).unwrap_or(Milliseconds::MAX))
}
fn frame_at(elapsed: Milliseconds) -> &'static str {
let frames = UI.spinner.active_frames();
let index = elapsed / UI.spinner.frame_ms;
frames[usize::try_from(index).unwrap_or_default() % frames.len()]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_busy_marker_advances_with_the_clock_and_wraps() {
let frames = UI.spinner.active_frames();
let at = |frame: usize| frame_at(frame as Milliseconds * UI.spinner.frame_ms);
assert_ne!(at(0), at(1));
assert_eq!(at(0), frames[0]);
assert_eq!(at(frames.len()), frames[0]);
assert_eq!(at(frames.len() + 1), frames[1]);
}
#[test]
fn a_frame_holds_for_its_whole_span() {
let span = UI.spinner.frame_ms;
assert_eq!(frame_at(0), frame_at(span - 1));
assert_ne!(frame_at(span - 1), frame_at(span));
}
}