yarli_cli/stream/
style.rs1use ratatui::style::{Color, Modifier, Style};
10
11use crate::mode::TerminalColorSupport;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Tier {
16 Urgent,
18 Active,
20 Contextual,
22 Background,
24}
25
26impl Tier {
27 pub fn style(self) -> Style {
29 self.style_for(TerminalColorSupport::detect_from_env())
30 }
31
32 pub fn style_for(self, support: TerminalColorSupport) -> Style {
33 match self {
34 Tier::Urgent => Style::default()
35 .fg(urgent_primary(support))
36 .add_modifier(Modifier::BOLD),
37 Tier::Active => Style::default()
38 .fg(active_primary(support))
39 .add_modifier(Modifier::BOLD),
40 Tier::Contextual => Style::default().fg(contextual_primary(support)),
41 Tier::Background => Style::default()
42 .fg(background_primary(support))
43 .add_modifier(Modifier::DIM),
44 }
45 }
46
47 pub fn accent(self) -> Style {
49 self.accent_for(TerminalColorSupport::detect_from_env())
50 }
51
52 pub fn accent_for(self, support: TerminalColorSupport) -> Style {
53 match self {
54 Tier::Urgent => Style::default()
55 .fg(urgent_accent(support))
56 .add_modifier(Modifier::BOLD),
57 Tier::Active => Style::default().fg(active_accent(support)),
58 Tier::Contextual => Style::default().fg(contextual_accent(support)),
59 Tier::Background => Style::default()
60 .fg(background_primary(support))
61 .add_modifier(Modifier::DIM),
62 }
63 }
64}
65
66fn urgent_primary(support: TerminalColorSupport) -> Color {
67 match support {
68 TerminalColorSupport::TrueColor => Color::Rgb(255, 107, 107),
69 TerminalColorSupport::Ansi16 | TerminalColorSupport::None => Color::Red,
70 }
71}
72
73fn urgent_accent(support: TerminalColorSupport) -> Color {
74 match support {
75 TerminalColorSupport::TrueColor => Color::Rgb(255, 209, 102),
76 TerminalColorSupport::Ansi16 | TerminalColorSupport::None => Color::Yellow,
77 }
78}
79
80fn active_primary(support: TerminalColorSupport) -> Color {
81 match support {
82 TerminalColorSupport::TrueColor => Color::Rgb(245, 247, 250),
83 TerminalColorSupport::Ansi16 | TerminalColorSupport::None => Color::White,
84 }
85}
86
87fn active_accent(support: TerminalColorSupport) -> Color {
88 match support {
89 TerminalColorSupport::TrueColor => Color::Rgb(78, 205, 196),
90 TerminalColorSupport::Ansi16 | TerminalColorSupport::None => Color::Cyan,
91 }
92}
93
94fn contextual_primary(support: TerminalColorSupport) -> Color {
95 match support {
96 TerminalColorSupport::TrueColor => Color::Rgb(146, 154, 171),
97 TerminalColorSupport::Ansi16 | TerminalColorSupport::None => Color::DarkGray,
98 }
99}
100
101fn contextual_accent(support: TerminalColorSupport) -> Color {
102 match support {
103 TerminalColorSupport::TrueColor => Color::Rgb(176, 184, 200),
104 TerminalColorSupport::Ansi16 | TerminalColorSupport::None => Color::Gray,
105 }
106}
107
108fn background_primary(support: TerminalColorSupport) -> Color {
109 match support {
110 TerminalColorSupport::TrueColor => Color::Rgb(92, 99, 112),
111 TerminalColorSupport::Ansi16 | TerminalColorSupport::None => Color::DarkGray,
112 }
113}
114
115pub fn tree_style() -> Style {
117 Tier::Background.style()
118}
119
120pub fn timestamp_style() -> Style {
122 Tier::Contextual.style()
123}
124
125pub fn arrow_style() -> Style {
127 Tier::Background.style()
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn urgent_is_bold_red() {
136 let s = Tier::Urgent.style_for(TerminalColorSupport::Ansi16);
137 assert_eq!(s.fg, Some(Color::Red));
138 assert!(s.add_modifier.contains(Modifier::BOLD));
139 }
140
141 #[test]
142 fn active_is_bold_white() {
143 let s = Tier::Active.style_for(TerminalColorSupport::Ansi16);
144 assert_eq!(s.fg, Some(Color::White));
145 assert!(s.add_modifier.contains(Modifier::BOLD));
146 }
147
148 #[test]
149 fn contextual_is_dark_gray() {
150 let s = Tier::Contextual.style_for(TerminalColorSupport::Ansi16);
151 assert_eq!(s.fg, Some(Color::DarkGray));
152 }
153
154 #[test]
155 fn background_is_dim_dark_gray() {
156 let s = Tier::Background.style_for(TerminalColorSupport::Ansi16);
157 assert_eq!(s.fg, Some(Color::DarkGray));
158 assert!(s.add_modifier.contains(Modifier::DIM));
159 }
160
161 #[test]
162 fn urgent_accent_is_yellow() {
163 let s = Tier::Urgent.accent_for(TerminalColorSupport::Ansi16);
164 assert_eq!(s.fg, Some(Color::Yellow));
165 }
166
167 #[test]
168 fn active_accent_is_cyan() {
169 let s = Tier::Active.accent_for(TerminalColorSupport::Ansi16);
170 assert_eq!(s.fg, Some(Color::Cyan));
171 }
172
173 #[test]
174 fn truecolor_active_accent_uses_rgb_palette() {
175 let s = Tier::Active.accent_for(TerminalColorSupport::TrueColor);
176 assert_eq!(s.fg, Some(Color::Rgb(78, 205, 196)));
177 }
178}