use std::io::{self, IsTerminal};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum PromptMode {
Interactive,
NonInteractive,
}
impl PromptMode {
#[must_use]
pub fn from_env() -> Self {
Self::from_stdio(io::stdin().is_terminal(), io::stderr().is_terminal())
}
#[must_use]
pub const fn from_stdio(stdin_is_tty: bool, stderr_is_tty: bool) -> Self {
if stdin_is_tty && stderr_is_tty {
Self::Interactive
} else {
Self::NonInteractive
}
}
#[must_use]
pub const fn is_interactive(self) -> bool {
matches!(self, Self::Interactive)
}
}
#[cfg(test)]
mod tests {
use super::PromptMode;
#[test]
fn interactive_requires_both_stdin_and_stderr_terminals() {
assert_eq!(PromptMode::from_stdio(true, true), PromptMode::Interactive);
assert_eq!(
PromptMode::from_stdio(true, false),
PromptMode::NonInteractive
);
assert_eq!(
PromptMode::from_stdio(false, true),
PromptMode::NonInteractive
);
assert_eq!(
PromptMode::from_stdio(false, false),
PromptMode::NonInteractive
);
assert!(PromptMode::Interactive.is_interactive());
assert!(!PromptMode::NonInteractive.is_interactive());
}
#[test]
fn from_env_resolves_against_the_process_stdio() {
assert_eq!(PromptMode::from_env(), PromptMode::NonInteractive);
}
}