soma_cli_core/
terminal.rs1use std::io::IsTerminal;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
17pub enum ColorMode {
18 #[default]
19 Auto,
20 Always,
21 Plain,
22}
23
24impl ColorMode {
25 pub fn parse(value: &str) -> Option<Self> {
28 match value {
29 "auto" => Some(Self::Auto),
30 "always" => Some(Self::Always),
31 "plain" | "never" => Some(Self::Plain),
32 _ => None,
33 }
34 }
35}
36
37pub fn resolve_color(mode: ColorMode, stream_is_tty: bool) -> bool {
43 match mode {
44 ColorMode::Always => true,
45 ColorMode::Plain => false,
46 ColorMode::Auto => stream_is_tty && std::env::var_os("NO_COLOR").is_none(),
47 }
48}
49
50pub fn is_stdin_terminal() -> bool {
52 std::io::stdin().is_terminal()
53}
54
55pub fn is_stdout_terminal() -> bool {
57 std::io::stdout().is_terminal()
58}
59
60pub fn is_stderr_terminal() -> bool {
62 std::io::stderr().is_terminal()
63}
64
65pub fn stderr_supports_color() -> bool {
68 resolve_color(ColorMode::Auto, is_stderr_terminal())
69}
70
71pub fn stdout_supports_color() -> bool {
74 resolve_color(ColorMode::Auto, is_stdout_terminal())
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn parse_accepts_known_values() {
83 assert_eq!(ColorMode::parse("auto"), Some(ColorMode::Auto));
84 assert_eq!(ColorMode::parse("always"), Some(ColorMode::Always));
85 assert_eq!(ColorMode::parse("plain"), Some(ColorMode::Plain));
86 assert_eq!(ColorMode::parse("never"), Some(ColorMode::Plain));
87 assert_eq!(ColorMode::parse("bogus"), None);
88 }
89
90 #[test]
91 fn always_and_plain_ignore_tty_state() {
92 assert!(resolve_color(ColorMode::Always, false));
93 assert!(!resolve_color(ColorMode::Plain, true));
94 }
95
96 #[test]
97 fn auto_requires_tty() {
98 assert!(!resolve_color(ColorMode::Auto, false));
99 }
100
101 #[test]
102 fn auto_respects_no_color_even_on_a_tty() {
103 let previous = std::env::var_os("NO_COLOR");
106 std::env::set_var("NO_COLOR", "1");
107 let result = resolve_color(ColorMode::Auto, true);
108 match previous {
109 Some(value) => std::env::set_var("NO_COLOR", value),
110 None => std::env::remove_var("NO_COLOR"),
111 }
112 assert!(!result, "NO_COLOR should disable Auto color even on a tty");
113 }
114}