use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum OutputMode {
#[default]
Normal,
Stream,
File(PathBuf),
Tui,
}
impl OutputMode {
pub fn from_args(stream: bool, output_dir: Option<PathBuf>) -> Self {
if let Some(dir) = output_dir {
OutputMode::File(dir)
} else if stream {
OutputMode::Stream
} else if is_tty() {
OutputMode::Tui
} else {
OutputMode::Normal
}
}
pub fn from_args_explicit(stream: bool, output_dir: Option<PathBuf>, enable_tui: bool) -> Self {
if let Some(dir) = output_dir {
OutputMode::File(dir)
} else if stream {
OutputMode::Stream
} else if enable_tui && is_tty() {
OutputMode::Tui
} else {
OutputMode::Normal
}
}
pub fn is_normal(&self) -> bool {
matches!(self, OutputMode::Normal)
}
pub fn is_stream(&self) -> bool {
matches!(self, OutputMode::Stream)
}
pub fn is_file(&self) -> bool {
matches!(self, OutputMode::File(_))
}
pub fn is_tui(&self) -> bool {
matches!(self, OutputMode::Tui)
}
pub fn output_dir(&self) -> Option<&PathBuf> {
match self {
OutputMode::File(dir) => Some(dir),
_ => None,
}
}
}
pub fn is_tty() -> bool {
use std::io::IsTerminal;
let is_terminal = std::io::stdout().is_terminal();
let is_ci = std::env::var("CI").is_ok()
|| std::env::var("GITHUB_ACTIONS").is_ok()
|| std::env::var("GITLAB_CI").is_ok()
|| std::env::var("JENKINS_URL").is_ok()
|| std::env::var("TRAVIS").is_ok();
is_terminal && !is_ci
}
pub fn should_use_colors() -> bool {
if !is_tty() {
return false;
}
if std::env::var("NO_COLOR").is_ok() {
return false;
}
if let Ok(term) = std::env::var("TERM") {
if term == "dumb" {
return false;
}
}
true
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_output_mode_from_args() {
let mode = OutputMode::from_args(false, None);
assert!(mode.is_normal());
let mode = OutputMode::from_args(true, None);
assert!(mode.is_stream());
let dir = PathBuf::from("/tmp/output");
let mode = OutputMode::from_args(true, Some(dir.clone()));
assert!(mode.is_file());
assert_eq!(mode.output_dir(), Some(&dir));
}
#[test]
fn test_output_mode_checks() {
let normal = OutputMode::Normal;
assert!(normal.is_normal());
assert!(!normal.is_stream());
assert!(!normal.is_file());
let stream = OutputMode::Stream;
assert!(!stream.is_normal());
assert!(stream.is_stream());
assert!(!stream.is_file());
let file = OutputMode::File(PathBuf::from("/tmp"));
assert!(!file.is_normal());
assert!(!file.is_stream());
assert!(file.is_file());
}
#[test]
fn test_default_output_mode() {
let mode = OutputMode::default();
assert!(mode.is_normal());
}
}