use anyhow::{anyhow, Result};
use std::sync::atomic::{AtomicU8, Ordering};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Interface {
Headless,
Tui,
Mcp,
}
impl Interface {
fn as_u8(self) -> u8 {
match self {
Interface::Headless => 0,
Interface::Tui => 1,
Interface::Mcp => 2,
}
}
fn from_u8(value: u8) -> Interface {
match value {
1 => Interface::Tui,
2 => Interface::Mcp,
_ => Interface::Headless,
}
}
}
static INTERFACE: AtomicU8 = AtomicU8::new(0);
pub fn set_interface(interface: Interface) {
INTERFACE.store(interface.as_u8(), Ordering::Relaxed);
}
pub fn current() -> Interface {
Interface::from_u8(INTERFACE.load(Ordering::Relaxed))
}
pub fn is_tui() -> bool {
current() == Interface::Tui
}
pub fn is_mcp() -> bool {
current() == Interface::Mcp
}
pub fn is_headless() -> bool {
current() == Interface::Headless
}
pub fn resolve(tui: bool, mcp: bool) -> Result<Interface> {
match (tui, mcp) {
(true, true) => Err(anyhow!(
"--tui and --mcp cannot be used together: choose one interface."
)),
(false, true) => Ok(Interface::Mcp),
(true, false) => Ok(Interface::Tui),
(false, false) => Ok(Interface::Headless),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn resolve_defaults_to_headless() {
assert_eq!(resolve(false, false).unwrap(), Interface::Headless);
}
#[test]
fn resolve_selects_tui_and_mcp() {
assert_eq!(resolve(true, false).unwrap(), Interface::Tui);
assert_eq!(resolve(false, true).unwrap(), Interface::Mcp);
}
#[test]
fn resolve_rejects_both_flags() {
assert!(resolve(true, true).is_err());
}
#[test]
fn set_and_read_roundtrip() {
set_interface(Interface::Tui);
assert!(is_tui());
assert!(!is_mcp());
set_interface(Interface::Mcp);
assert!(is_mcp());
set_interface(Interface::Headless);
assert!(is_headless());
}
}