#![allow(dead_code)]
use crate::config::ColorMode;
use std::io::IsTerminal;
pub fn is_stdout_tty() -> bool {
std::io::stdout().is_terminal()
}
pub fn is_stdin_tty() -> bool {
std::io::stdin().is_terminal()
}
pub fn should_use_colors_with_mode(color_mode: &ColorMode) -> bool {
match color_mode {
ColorMode::Never => false,
ColorMode::Always => {
true
}
ColorMode::Auto => should_use_colors_auto(),
}
}
fn should_use_colors_auto() -> bool {
if !is_stdout_tty() {
return false;
}
if std::env::var("NO_COLOR").is_ok() {
return false;
}
if std::env::var("FORCE_COLOR").is_ok() {
return true;
}
true
}
pub fn get_terminal_width() -> usize {
if let Ok(columns_str) = std::env::var("COLUMNS") {
if let Ok(columns) = columns_str.parse::<usize>() {
if columns > 0 {
return columns;
}
}
}
if let Some((terminal_size::Width(width), _)) = terminal_size::terminal_size() {
width as usize
} else {
100
}
}
#[cfg(test)]
mod tests {
use super::*;
use once_cell::sync::Lazy;
use std::sync::Mutex;
static ENV_LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
struct EnvGuard {
vars: Vec<(&'static str, Option<String>)>,
}
impl EnvGuard {
fn new(keys: &[&'static str]) -> Self {
let vars = keys
.iter()
.map(|key| (*key, std::env::var(key).ok()))
.collect();
Self { vars }
}
}
impl Drop for EnvGuard {
fn drop(&mut self) {
for (key, value) in &self.vars {
if let Some(v) = value {
std::env::set_var(key, v);
} else {
std::env::remove_var(key);
}
}
}
}
fn with_env_lock<F: FnOnce()>(keys: &[&'static str], f: F) {
let _lock = ENV_LOCK.lock().unwrap();
let _guard = EnvGuard::new(keys);
f();
}
#[test]
fn color_mode_never_disables_colors() {
assert!(!should_use_colors_with_mode(&ColorMode::Never));
}
#[test]
fn color_mode_always_overrides_no_color_environment() {
with_env_lock(&["NO_COLOR"], || {
std::env::set_var("NO_COLOR", "1");
assert!(should_use_colors_with_mode(&ColorMode::Always));
});
}
#[test]
fn terminal_width_uses_columns_env_var() {
with_env_lock(&["COLUMNS"], || {
std::env::set_var("COLUMNS", "120");
assert_eq!(get_terminal_width(), 120);
});
}
#[test]
fn terminal_width_ignores_invalid_columns() {
with_env_lock(&["COLUMNS"], || {
std::env::set_var("COLUMNS", "invalid");
let width = get_terminal_width();
assert!(width > 0);
});
}
#[test]
fn terminal_width_ignores_zero_columns() {
with_env_lock(&["COLUMNS"], || {
std::env::set_var("COLUMNS", "0");
let width = get_terminal_width();
assert!(width > 0);
});
}
#[test]
fn terminal_width_fallback_when_columns_unset() {
with_env_lock(&["COLUMNS"], || {
std::env::remove_var("COLUMNS");
let width = get_terminal_width();
assert!(width > 0);
});
}
}