use std::io::IsTerminal;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum DebugMode {
#[default]
Auto,
Always,
Never,
}
impl DebugMode {
#[must_use]
pub fn wants_repl(self) -> bool {
match self {
DebugMode::Always => true,
DebugMode::Never => false,
DebugMode::Auto => std::io::stdin().is_terminal() && std::io::stdout().is_terminal(),
}
}
}
impl std::str::FromStr for DebugMode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"auto" => Ok(DebugMode::Auto),
"always" => Ok(DebugMode::Always),
"never" => Ok(DebugMode::Never),
other => Err(format!(
"unknown --debug mode `{other}` (expected auto|always|never)"
)),
}
}
}
impl std::fmt::Display for DebugMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
DebugMode::Auto => "auto",
DebugMode::Always => "always",
DebugMode::Never => "never",
};
f.write_str(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_auto_always_never() {
assert_eq!("auto".parse::<DebugMode>().unwrap(), DebugMode::Auto);
assert_eq!("always".parse::<DebugMode>().unwrap(), DebugMode::Always);
assert_eq!("never".parse::<DebugMode>().unwrap(), DebugMode::Never);
}
#[test]
fn rejects_unknown_mode() {
assert!("yes".parse::<DebugMode>().is_err());
assert!("".parse::<DebugMode>().is_err());
}
#[test]
fn always_wants_repl_never_does_not() {
assert!(DebugMode::Always.wants_repl());
assert!(!DebugMode::Never.wants_repl());
}
}