1use std::io::IsTerminal;
6
7#[derive(Clone, Copy, Debug)]
8pub struct Style {
9 enabled: bool,
10}
11
12impl Style {
13 pub fn stdout(no_color: bool) -> Self {
14 Self::new(no_color, std::io::stdout().is_terminal())
15 }
16
17 pub fn stderr(no_color: bool) -> Self {
18 Self::new(no_color, std::io::stderr().is_terminal())
19 }
20
21 fn new(no_color: bool, is_terminal: bool) -> Self {
22 let env_disabled = std::env::var_os("NO_COLOR").is_some();
23 Self {
24 enabled: is_terminal && !no_color && !env_disabled,
25 }
26 }
27
28 fn paint(&self, code: &str, text: impl AsRef<str>) -> String {
29 let text = text.as_ref();
30 if self.enabled {
31 format!("\x1b[{code}m{text}\x1b[0m")
32 } else {
33 text.to_string()
34 }
35 }
36
37 pub fn bold(&self, text: impl AsRef<str>) -> String {
38 self.paint("1", text)
39 }
40
41 pub fn dim(&self, text: impl AsRef<str>) -> String {
42 self.paint("2", text)
43 }
44
45 pub fn blue(&self, text: impl AsRef<str>) -> String {
46 self.paint("34", text)
47 }
48
49 pub fn cyan(&self, text: impl AsRef<str>) -> String {
50 self.paint("36", text)
51 }
52
53 pub fn green(&self, text: impl AsRef<str>) -> String {
54 self.paint("32", text)
55 }
56
57 pub fn yellow(&self, text: impl AsRef<str>) -> String {
58 self.paint("33", text)
59 }
60
61 pub fn red(&self, text: impl AsRef<str>) -> String {
62 self.paint("31", text)
63 }
64}