#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Page {
#[default]
Jobs,
Models,
Worker,
Logs,
Config,
}
impl Page {
pub const ALL: [Page; 5] = [
Page::Jobs,
Page::Models,
Page::Worker,
Page::Logs,
Page::Config,
];
pub fn label(self) -> &'static str {
match self {
Page::Jobs => "Jobs",
Page::Models => "Models",
Page::Worker => "Worker",
Page::Logs => "Logs",
Page::Config => "Config",
}
}
pub fn hint(self) -> &'static str {
match self {
Page::Jobs => "What runs now and what ran",
Page::Models => "Load and unload models",
Page::Worker => "State, registration, hardware and version",
Page::Logs => "Everything the daemon logs",
Page::Config => "Worker settings and this window",
}
}
pub fn from_digit(digit: u8) -> Option<Self> {
Self::ALL.get(usize::from(digit).checked_sub(1)?).copied()
}
pub fn digit(self) -> u8 {
Self::ALL.iter().position(|p| *p == self).unwrap_or(0) as u8 + 1
}
pub fn parse(name: &str) -> Option<Self> {
let name = name.trim();
Self::ALL
.into_iter()
.find(|p| p.label().eq_ignore_ascii_case(name))
}
pub fn initial() -> Self {
Self::initial_from(std::env::var("STUDIO_WORKER_UI_PAGE").ok().as_deref())
}
pub fn initial_from(env: Option<&str>) -> Self {
env.and_then(Self::parse).unwrap_or_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_rail_lists_every_page_in_order() {
let labels: Vec<&str> = Page::ALL.iter().map(|p| p.label()).collect();
assert_eq!(labels, ["Jobs", "Models", "Worker", "Logs", "Config"]);
}
#[test]
fn the_window_opens_on_jobs() {
assert_eq!(Page::default(), Page::Jobs);
assert_eq!(Page::initial_from(None), Page::Jobs);
assert_eq!(Page::initial_from(Some("nonsense")), Page::Jobs);
assert_eq!(Page::initial_from(Some("worker")), Page::Worker);
}
#[test]
fn names_parse_case_insensitively_and_old_tabs_are_gone() {
for page in Page::ALL {
assert_eq!(Page::parse(page.label()), Some(page));
assert_eq!(Page::parse(&page.label().to_uppercase()), Some(page));
assert!(!page.hint().is_empty());
}
assert_eq!(Page::parse(" logs "), Some(Page::Logs));
assert_eq!(Page::parse("status"), None);
assert_eq!(Page::parse("about"), None);
}
#[test]
fn digits_pick_pages_in_rail_order() {
for page in Page::ALL {
assert_eq!(Page::from_digit(page.digit()), Some(page));
}
assert_eq!(Page::from_digit(1), Some(Page::Jobs));
assert_eq!(Page::from_digit(0), None);
assert_eq!(Page::from_digit(6), None);
}
}