vela_protocol/
cli_style.rs1use colored::{ColoredString, Colorize};
17use indicatif::ProgressStyle;
18use std::io::IsTerminal;
19use std::sync::Once;
20
21pub const MOSS: (u8, u8, u8) = (0x3F, 0x6B, 0x4E);
24pub const BRASS: (u8, u8, u8) = (0x8A, 0x6A, 0x1F);
25pub const DUST: (u8, u8, u8) = (0x7A, 0x6F, 0x5C);
26pub const MADDER: (u8, u8, u8) = (0x8A, 0x3A, 0x3A);
27pub const SIGNAL: (u8, u8, u8) = (0x3B, 0x5B, 0xDB);
28
29static INIT: Once = Once::new();
32
33pub fn init() {
38 INIT.call_once(|| {
39 let no_color = std::env::var_os("NO_COLOR").is_some();
40 let is_tty = std::io::stdout().is_terminal();
41 if no_color || !is_tty {
42 colored::control::set_override(false);
43 }
44 });
45}
46
47#[must_use]
50pub fn dim(s: &str) -> ColoredString {
51 s.dimmed()
52}
53
54#[must_use]
55pub fn mono_eyebrow(label: &str) -> ColoredString {
56 label.dimmed()
58}
59
60#[must_use]
62pub fn tick_row(width: usize) -> String {
63 let row = "·".repeat(width);
64 format!("{}", row.dimmed())
65}
66
67#[must_use]
73pub fn moss(s: impl AsRef<str>) -> ColoredString {
74 let (r, g, b) = MOSS;
75 s.as_ref().truecolor(r, g, b)
76}
77
78#[must_use]
79pub fn madder(s: impl AsRef<str>) -> ColoredString {
80 let (r, g, b) = MADDER;
81 s.as_ref().truecolor(r, g, b)
82}
83
84#[must_use]
85pub fn brass(s: impl AsRef<str>) -> ColoredString {
86 let (r, g, b) = BRASS;
87 s.as_ref().truecolor(r, g, b)
88}
89
90#[must_use]
91pub fn dust_color(s: impl AsRef<str>) -> ColoredString {
92 let (r, g, b) = DUST;
93 s.as_ref().truecolor(r, g, b)
94}
95
96#[must_use]
97pub fn signal(s: impl AsRef<str>) -> ColoredString {
98 let (r, g, b) = SIGNAL;
99 s.as_ref().truecolor(r, g, b)
100}
101
102#[must_use]
106pub fn chip(label: &str, rgb: (u8, u8, u8)) -> String {
107 let dot = "·".truecolor(rgb.0, rgb.1, rgb.2);
108 let text = label.truecolor(rgb.0, rgb.1, rgb.2);
109 format!("{dot} {text}")
110}
111
112#[must_use]
113pub fn ok(label: &str) -> String {
114 chip(label, MOSS)
115}
116
117#[must_use]
118pub fn warn(label: &str) -> String {
119 chip(label, BRASS)
120}
121
122#[must_use]
123pub fn stale(label: &str) -> String {
124 chip(label, DUST)
125}
126
127#[must_use]
128pub fn lost(label: &str) -> String {
129 chip(label, MADDER)
130}
131
132#[must_use]
134pub fn live(label: &str) -> String {
135 chip(label, SIGNAL)
136}
137
138pub fn header(eyebrow: &str, title: &str) {
144 println!(" {}", eyebrow.dimmed());
145 println!(" {}", title.bold());
146 println!(" {}", tick_row(60));
147}
148
149#[must_use]
151pub fn err_prefix() -> String {
152 let (r, g, b) = MADDER;
153 format!("{}", "err ·".truecolor(r, g, b))
154}
155
156#[must_use]
163pub fn progress_style(unit: &str) -> ProgressStyle {
164 let template = format!(" {{bar:30}} {{pos}}/{{len}} · {unit} · {{msg}}");
165 ProgressStyle::with_template(&template)
166 .unwrap_or_else(|_| ProgressStyle::default_bar())
167 .progress_chars("──╌")
168}