big_code_analysis/output/color.rs
1//! Color-mode selection for the terminal dump serializers.
2//!
3//! The library deliberately performs **no** environment or tty
4//! inspection itself: a binary embedding `big-code-analysis` owns the
5//! policy decision of whether its stdout is a terminal, whether
6//! `NO_COLOR` is set, and whether the user passed a `--color` flag. The
7//! caller resolves those signals into a [`ColorMode`] and hands it to
8//! the `*_with_color` dump entry points; the library only translates
9//! that choice into a concrete [`termcolor::ColorChoice`].
10//!
11//! Keeping the detection out of the library avoids surprising a
12//! downstream embedder whose process is not the `bca` CLI (a GUI, an
13//! LSP server, a test harness) with implicit reads of `NO_COLOR` or the
14//! ambient `TERM`.
15
16use termcolor::ColorChoice;
17
18/// Whether the terminal dump serializers ([`crate::dump_root`],
19/// [`crate::dump_ops`], [`crate::dump_node`],
20/// [`crate::dump_function_spans`]) emit ANSI color escapes.
21///
22/// This is the library-facing color policy. The CLI resolves user
23/// intent (an explicit `--color` flag, the `NO_COLOR` convention, and
24/// stdout tty detection) into one of these variants and threads it into
25/// the `*_with_color` dump entry points.
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
27pub enum ColorMode {
28 /// Color only when the underlying stream and environment permit it.
29 ///
30 /// Maps to [`termcolor::ColorChoice::Auto`], which honors `NO_COLOR`
31 /// and `TERM=dumb`. Note that `Auto` does **not** itself check
32 /// whether stdout is a terminal — a caller that wants
33 /// "no color when piped" must resolve a redirected stream to
34 /// [`ColorMode::Never`] before constructing the writer (the CLI
35 /// does this via `std::io::IsTerminal`).
36 #[default]
37 Auto,
38 /// Always emit color escapes, regardless of stream or environment.
39 Always,
40 /// Never emit color escapes.
41 Never,
42}
43
44impl ColorMode {
45 /// Translate the policy into the concrete `termcolor` choice used to
46 /// construct a [`termcolor::StandardStream`].
47 pub(crate) fn to_color_choice(self) -> ColorChoice {
48 match self {
49 Self::Auto => ColorChoice::Auto,
50 Self::Always => ColorChoice::Always,
51 Self::Never => ColorChoice::Never,
52 }
53 }
54}