Coverage Report

Created: 2025-12-08 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/anstyle-query-1.1.5/src/lib.rs
Line
Count
Source
1
//! Low level terminal capability lookups
2
3
#![cfg_attr(docsrs, feature(doc_cfg))]
4
#![warn(missing_docs)]
5
#![warn(clippy::print_stderr)]
6
#![warn(clippy::print_stdout)]
7
8
pub mod windows;
9
10
/// Check [CLICOLOR] status
11
///
12
/// - When `true`, ANSI colors are supported and should be used when the program isn't piped,
13
///   similar to [`term_supports_color`]
14
/// - When `false`, don’t output ANSI color escape codes, similar to [`no_color`]
15
///
16
/// See also:
17
/// - [terminfo](https://crates.io/crates/terminfo) or [term](https://crates.io/crates/term) for
18
///   checking termcaps
19
/// - [termbg](https://crates.io/crates/termbg) for detecting background color
20
///
21
/// [CLICOLOR]: https://bixense.com/clicolors/
22
#[inline]
23
4
pub fn clicolor() -> Option<bool> {
24
4
    let value = std::env::var_os("CLICOLOR")?;
25
0
    Some(value != "0")
26
4
}
27
28
/// Check [CLICOLOR_FORCE] status
29
///
30
/// ANSI colors should be enabled no matter what.
31
///
32
/// [CLICOLOR_FORCE]: https://bixense.com/clicolors/
33
#[inline]
34
4
pub fn clicolor_force() -> bool {
35
4
    non_empty(std::env::var_os("CLICOLOR_FORCE").as_deref())
36
4
}
37
38
/// Check [NO_COLOR] status
39
///
40
/// When `true`, should prevent the addition of ANSI color.
41
///
42
/// User-level configuration files and per-instance command-line arguments should override
43
/// [NO_COLOR]. A user should be able to export `$NO_COLOR` in their shell configuration file as a
44
/// default, but configure a specific program in its configuration file to specifically enable
45
/// color.
46
///
47
/// [NO_COLOR]: https://no-color.org/
48
#[inline]
49
4
pub fn no_color() -> bool {
50
4
    non_empty(std::env::var_os("NO_COLOR").as_deref())
51
4
}
52
53
/// Check `TERM` for color support
54
#[inline]
55
0
pub fn term_supports_color() -> bool {
56
    #[cfg(not(windows))]
57
    {
58
0
        match std::env::var_os("TERM") {
59
            // If TERM isn't set, then we are in a weird environment that
60
            // probably doesn't support colors.
61
0
            None => return false,
62
0
            Some(k) => {
63
0
                if k == "dumb" {
64
0
                    return false;
65
0
                }
66
            }
67
        }
68
0
        true
69
    }
70
    #[cfg(windows)]
71
    {
72
        // On Windows, if TERM isn't set, then we shouldn't automatically
73
        // assume that colors aren't allowed. This is unlike Unix environments
74
        // where TERM is more rigorously set.
75
        if let Some(k) = std::env::var_os("TERM") {
76
            if k == "dumb" {
77
                return false;
78
            }
79
        }
80
        true
81
    }
82
0
}
83
84
/// Check `TERM` for ANSI color support
85
///
86
/// On Windows, you might need to also check [`windows::enable_ansi_colors`] as ANSI color support
87
/// is opt-in, rather than assumed.
88
#[inline]
89
pub fn term_supports_ansi_color() -> bool {
90
    #[cfg(not(windows))]
91
    {
92
        term_supports_color()
93
    }
94
    #[cfg(windows)]
95
    {
96
        match std::env::var_os("TERM") {
97
            None => return false,
98
            Some(k) => {
99
                // cygwin doesn't seem to support ANSI escape sequences
100
                // and instead has its own variety. However, the Windows
101
                // console API may be available.
102
                if k == "dumb" || k == "cygwin" {
103
                    return false;
104
                }
105
            }
106
        }
107
        true
108
    }
109
}
110
111
/// Check [COLORTERM] for truecolor support
112
///
113
/// [COLORTERM]: https://github.com/termstandard/colors
114
#[inline]
115
pub fn truecolor() -> bool {
116
    let value = std::env::var_os("COLORTERM");
117
    let value = value.as_deref().unwrap_or_default();
118
    value == "truecolor" || value == "24bit"
119
}
120
121
/// Report whether this is running in CI
122
///
123
/// CI is a common environment where, despite being piped, ansi color codes are supported
124
///
125
/// This is not as exhaustive as you'd find in a crate like `is_ci` but it should work in enough
126
/// cases.
127
#[inline]
128
0
pub fn is_ci() -> bool {
129
    // Assuming its CI based on presence because who would be setting `CI=false`?
130
    //
131
    // This makes it easier to all of the potential values when considering our known values:
132
    // - Gitlab and Github set it to `true`
133
    // - Woodpecker sets it to `woodpecker`
134
0
    std::env::var_os("CI").is_some()
135
0
}
136
137
8
fn non_empty(var: Option<&std::ffi::OsStr>) -> bool {
138
8
    !var.unwrap_or_default().is_empty()
139
8
}
140
141
#[cfg(test)]
142
mod test {
143
    use super::*;
144
145
    #[test]
146
    fn non_empty_not_present() {
147
        assert!(!non_empty(None));
148
    }
149
150
    #[test]
151
    fn non_empty_empty() {
152
        assert!(!non_empty(Some(std::ffi::OsStr::new(""))));
153
    }
154
155
    #[test]
156
    fn non_empty_texty() {
157
        assert!(non_empty(Some(std::ffi::OsStr::new("hello"))));
158
    }
159
}
160
161
#[doc = include_str!("../README.md")]
162
#[cfg(doctest)]
163
pub struct ReadmeDoctests;