1use std::sync::LazyLock;
2
3pub struct Colors {
4 pub reset: &'static str,
5 pub blue: &'static str,
6 pub cyan: &'static str,
7 pub green: &'static str,
8 pub yellow: &'static str,
9 pub red: &'static str,
10 pub magenta: &'static str,
11}
12
13impl Colors {
14 const fn new(is_no_color: bool) -> Self {
15 if is_no_color {
16 Self {
17 reset: "",
18 blue: "",
19 cyan: "",
20 green: "",
21 yellow: "",
22 red: "",
23 magenta: "",
24 }
25 } else {
26 Self {
27 reset: "\x1b[0m",
28 blue: "\x1b[34m",
29 cyan: "\x1b[36m",
30 green: "\x1b[32m",
31 yellow: "\x1b[33m",
32 red: "\x1b[31m",
33 magenta: "\x1b[35m",
34 }
35 }
36 }
37}
38
39pub static COLORS: LazyLock<Colors> = LazyLock::new(|| {
40 const NO_COLOR: *const libc::c_char = c"NO_COLOR".as_ptr();
41 let is_no_color = unsafe { !libc::getenv(NO_COLOR).is_null() };
42 Colors::new(is_no_color)
43});
44
45#[must_use]
46#[cfg_attr(feature = "hotpath", hotpath::measure)]
47pub fn print_dots() -> String {
48 const GLYPH: &str = "";
50 let capacity = COLORS.blue.len()
51 + COLORS.cyan.len()
52 + COLORS.green.len()
53 + COLORS.yellow.len()
54 + COLORS.red.len()
55 + COLORS.magenta.len()
56 + COLORS.reset.len()
57 + (GLYPH.len() + 2) * 6;
58
59 let mut result = String::with_capacity(capacity);
60 result.push_str(COLORS.blue);
61 result.push_str(GLYPH);
62 result.push_str(" ");
63 result.push_str(COLORS.cyan);
64 result.push_str(GLYPH);
65 result.push_str(" ");
66 result.push_str(COLORS.green);
67 result.push_str(GLYPH);
68 result.push_str(" ");
69 result.push_str(COLORS.yellow);
70 result.push_str(GLYPH);
71 result.push_str(" ");
72 result.push_str(COLORS.red);
73 result.push_str(GLYPH);
74 result.push_str(" ");
75 result.push_str(COLORS.magenta);
76 result.push_str(GLYPH);
77 result.push_str(" ");
78 result.push_str(COLORS.reset);
79
80 result
81}