use ratatui::style::{Modifier, Style};
pub(super) const STATUS_CYCLE: &[&str] = &[
"None", "Napkin", "First", "Second", "Third", "Final", "Ready",
];
#[cfg(test)]
#[allow(dead_code)]
pub(super) fn digit_to_status(c: char) -> Option<&'static str> {
match c {
'1' => Some("Ready"),
'2' => Some("Final"),
'3' => Some("Third"),
'4' => Some("Second"),
'5' => Some("First"),
'6' => Some("Napkin"),
'7' => Some("None"),
_ => None,
}
}
pub(super) fn next_status(current: Option<&str>) -> &'static str {
let cur = display_status(current);
let idx = STATUS_CYCLE.iter().position(|s| *s == cur).unwrap_or(0);
STATUS_CYCLE[(idx + 1) % STATUS_CYCLE.len()]
}
pub(super) fn prev_status(current: Option<&str>) -> &'static str {
let cur = display_status(current);
let idx = STATUS_CYCLE.iter().position(|s| *s == cur).unwrap_or(0);
STATUS_CYCLE[(idx + STATUS_CYCLE.len() - 1) % STATUS_CYCLE.len()]
}
pub(super) fn display_status(current: Option<&str>) -> &str {
match current {
None => "None",
Some(s) if s.trim().is_empty() => "None",
Some(s) => s,
}
}
pub(super) fn status_letter(label: &str) -> &'static str {
match label {
"Napkin" => "n",
"First" => "1",
"Second" => "2",
"Third" => "3",
"Final" => "F",
"Ready" => "R",
_ => " ",
}
}
pub(super) fn status_style(label: &str, theme: &super::theme::Theme) -> Style {
let base = match label {
"None" => return Style::default().add_modifier(Modifier::DIM),
"Napkin" => theme.grammar_change_fg, "First" => theme.ai_scope_fg, "Second" => theme.characters_fg, "Third" => theme.places_fg, "Final" => theme.border_saved, "Ready" => theme.border_saved, _ => return Style::default(),
};
let mut style = Style::default().fg(base).add_modifier(Modifier::BOLD);
if label == "Ready" {
style = style.add_modifier(Modifier::REVERSED);
}
style
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn digit_to_status_mapping() {
assert_eq!(digit_to_status('1'), Some("Ready"));
assert_eq!(digit_to_status('2'), Some("Final"));
assert_eq!(digit_to_status('3'), Some("Third"));
assert_eq!(digit_to_status('4'), Some("Second"));
assert_eq!(digit_to_status('5'), Some("First"));
assert_eq!(digit_to_status('6'), Some("Napkin"));
assert_eq!(digit_to_status('7'), Some("None"));
assert_eq!(digit_to_status('0'), None);
assert_eq!(digit_to_status('8'), None);
assert_eq!(digit_to_status('a'), None);
}
#[test]
fn status_letter_returns_one_char_or_space() {
assert_eq!(status_letter("Napkin"), "n");
assert_eq!(status_letter("First"), "1");
assert_eq!(status_letter("Second"), "2");
assert_eq!(status_letter("Third"), "3");
assert_eq!(status_letter("Final"), "F");
assert_eq!(status_letter("Ready"), "R");
assert_eq!(status_letter("None"), " ");
assert_eq!(status_letter("Unknown"), " ");
}
#[test]
fn next_status_walks_the_ring() {
assert_eq!(next_status(None), "Napkin");
assert_eq!(next_status(Some("Napkin")), "First");
assert_eq!(next_status(Some("First")), "Second");
assert_eq!(next_status(Some("Second")), "Third");
assert_eq!(next_status(Some("Third")), "Final");
assert_eq!(next_status(Some("Final")), "Ready");
assert_eq!(next_status(Some("Ready")), "None");
assert_eq!(next_status(Some("")), "Napkin");
}
#[test]
fn prev_status_walks_backwards_and_wraps() {
assert_eq!(prev_status(Some("Napkin")), "None");
assert_eq!(prev_status(Some("Ready")), "Final");
assert_eq!(prev_status(Some("Final")), "Third");
assert_eq!(prev_status(None), "Ready"); }
#[test]
fn next_status_unknown_value_treated_as_none() {
assert_eq!(next_status(Some("WeirdCustom")), "Napkin");
}
#[test]
fn display_status_collapses_none_variants() {
assert_eq!(display_status(None), "None");
assert_eq!(display_status(Some("")), "None");
assert_eq!(display_status(Some(" ")), "None");
assert_eq!(display_status(Some("Napkin")), "Napkin");
}
}