concolor_control/lib.rs
1//! Control console coloring across all dependencies
2//!
3//! # Motivation
4//!
5//! Detecting a terminal's color capabilities and passing it down to each writer
6//! can be obnoxious. Some crates try to make this easier by detecting the environment for you and
7//! making their own choice to print colors. As an application author, you own the experience for
8//! your application and want the behavior to be consistent. To get this, you have to dig into
9//! each crate's implementation to see how they auto-detect color capabilities and, if they don't
10//! do it how you want, hope they provide a way to override it so you can implement it yourself.
11//!
12//! Like with logging, your terminal's capabilities and how to treat it is a behavior that cuts
13//! across your application. So to make things more consistent and easier to control,
14//! `concolor-control` introduces shared detection logic that all crates can call into to get
15//! consistent behavior. The application author can then choose what feature flags are enabled to
16//! decide on what the end-user experience should be.
17//!
18//! # `[[bin]]`s
19//!
20//! ```toml
21//! [dependencies]
22//! concolor-control = { version = "0.0.7", features = "color" }
23//! ```
24//! Notes:
25//! - With the
26//! [2021 edition / `resolver = "2"`](https://doc.rust-lang.org/nightly/edition-guide/rust-2021/default-cargo-resolver.html),
27//! you will also need to specify this in your `build-dependencies` if you want `build.rs` to have color
28//! as well.
29//!
30//! If you are providing a command line option for controlling color, just call
31//! ```rust
32//! let when = concolor_control::ColorChoice::Always;
33//! concolor_control::set(when);
34//! ```
35//!
36//! See also [`concolor-clap`](https://docs.rs/concolor-clap)
37//!
38//! # `[lib]`s
39//!
40//! The `[[bin]]` is responsible for defining the policy of how colors are determined, so to depend
41//! on `concolor-control`:
42//! ```toml
43//! [dependencies]
44//! concolor-control = { version = "0.0.7", default-features = false }
45//! ```
46//!
47//! At times, you might want to provide a convenience feature for color support, so you could also:
48//! ```toml
49//! [features]
50//! default = ["color"]
51//! color = "concolor-control/auto"
52//!
53//! [dependencies]
54//! concolor-control = { version = "0.0.7", optional = True}
55//! ```
56//! Notes:
57//! - Your choice on whether to make this default or not
58//! - Depending on your context, name it either `color` (for a crate like `clap`) or `auto` (for a
59//! crate like `termcolor`)
60//!
61//! Then just ask as needed:
62//! ```rust
63//! let stdout_support = concolor_control::get(concolor_control::Stream::Stdout);
64//! if stdout_support.ansi_color() {
65//! // Output ANSI escape sequences
66//! if stdout_support.truecolor() {
67//! // Get even fancier with the colors
68//! }
69//! } else if stdout_support.color() {
70//! // Legacy Windows version, control the console as needed
71//! } else {
72//! // No coloring
73//! }
74//! ```
75//!
76//! # Features
77//!
78//! - `auto`: Guess color status based on all possible sources, including:
79//! - `api_unstable`: Allow controlling color via the API (until 1.0, this is not guaranteed to
80//! work across crates which is why this is `_unstable`)
81//! - `interactive`: Check if stdout/stderr is a TTY
82//! - `clicolor`: Respect [CLICOLOR] spec
83//! - `no_color`: Respect [NO_COLOR] spec
84//! - `term`: Check `TERM`
85//! - `windows`: Check if we can enable ANSI support
86//!
87//! [CLICOLOR]: https://bixense.com/clicolors/
88//! [NO_COLOR]: https://no-color.org/
89
90#![cfg_attr(not(feature = "std"), no_std)]
91
92#[cfg(feature = "core")]
93mod color;
94#[cfg(feature = "core")]
95pub use color::*;
96
97#[cfg(not(feature = "core"))]
98mod no_color;
99#[cfg(not(feature = "core"))]
100pub use no_color::*;
101
102mod choice;
103pub use choice::*;
104mod stream;
105pub use stream::*;