use std::time::Instant;
const STATUS_INDICATOR_FRAME_MS: u128 = 420;
const STATUS_INDICATOR_DOT_FRAMES: &[&str] = &["◍", "◉", "◌", "◌", "◉", "◍"];
#[must_use]
pub fn header_status_indicator_frame(
turn_started_at: Option<Instant>,
mode: &str,
) -> Option<&'static str> {
let frames: &[&str] = match mode.trim().to_ascii_lowercase().as_str() {
"off" | "none" | "hidden" | "false" => return None,
"dots" | "dot" => STATUS_INDICATOR_DOT_FRAMES,
_ => return Some("cw"),
};
let elapsed_ms = turn_started_at
.map(|t| t.elapsed().as_millis())
.unwrap_or(0);
let idx = (elapsed_ms / STATUS_INDICATOR_FRAME_MS) as usize % frames.len();
Some(frames[idx])
}
#[cfg(test)]
mod tests {
#[test]
fn legacy_whale_indicator_settings_normalize_to_the_cw_mark() {
for legacy in ["whale", "🐳", "🐋"] {
assert_eq!(
super::header_status_indicator_frame(None, legacy),
Some("cw"),
"legacy mode {legacy:?} must normalize to the cw mark"
);
assert_eq!(
super::header_status_indicator_frame(Some(std::time::Instant::now()), legacy),
Some("cw"),
"legacy mode {legacy:?} must stay static mid-turn"
);
}
}
#[test]
fn cw_indicator_is_static_and_typographic() {
assert_eq!(super::header_status_indicator_frame(None, "cw"), Some("cw"));
assert_eq!(
super::header_status_indicator_frame(Some(std::time::Instant::now()), "cw"),
Some("cw")
);
}
#[test]
fn dots_indicator_uses_geometric_frames() {
let frame = super::header_status_indicator_frame(None, "dots");
assert_eq!(frame, Some("\u{25CD}"));
}
#[test]
fn off_indicator_returns_none_so_chip_is_hidden() {
assert!(super::header_status_indicator_frame(None, "off").is_none());
assert!(super::header_status_indicator_frame(None, "none").is_none());
assert!(super::header_status_indicator_frame(None, "hidden").is_none());
assert!(super::header_status_indicator_frame(None, "false").is_none());
}
#[test]
fn unknown_indicator_mode_defaults_to_cw() {
let frame = super::header_status_indicator_frame(None, "wahel-typo");
assert_eq!(frame, Some("cw"));
}
#[test]
fn whale_glyphs_have_narrow_ascii_fallbacks() {
assert_eq!(crate::tui::glyphs::ascii_fallback("🐳"), Some("w"));
assert_eq!(crate::tui::glyphs::ascii_fallback("🐋"), Some("w"));
}
}