1use okf_core::{ActorKind, Status, TrustTier};
10use ratatui::style::{Color, Modifier, Style};
11
12pub const GLYPH_CONCEPT: &str = "●";
14pub const GLYPH_COMPUTATION: &str = "⚙";
16pub const GLYPH_INDEX: &str = "◈";
18pub const GLYPH_LOG: &str = "≡";
20pub const GLYPH_BROKEN: &str = "✗";
22pub const GLYPH_WARN: &str = "⚠";
24pub const GLYPH_STALE_SOON: &str = "⏳";
26pub const GLYPH_FIXABLE: &str = "✚";
28pub const GLYPH_OK: &str = "✔";
30
31pub const SPINNER_FRAMES: [&str; 10] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
33
34#[derive(Clone, Copy, Debug)]
36pub struct Theme {
37 pub color: bool,
39}
40
41impl Default for Theme {
42 fn default() -> Self {
43 Self::from_env()
44 }
45}
46
47impl Theme {
48 #[must_use]
50 pub fn from_env() -> Self {
51 Self {
52 color: std::env::var_os("NO_COLOR").is_none_or(|v| v.is_empty()),
53 }
54 }
55
56 #[must_use]
58 pub const fn with_color(color: bool) -> Self {
59 Self { color }
60 }
61
62 fn fg(self, color: Color) -> Style {
63 if self.color {
64 Style::default().fg(color)
65 } else {
66 Style::default()
67 }
68 }
69
70 #[must_use]
72 pub fn accent(self) -> Style {
73 self.fg(Color::Cyan)
74 }
75
76 #[must_use]
78 pub fn dim(self) -> Style {
79 Style::default().add_modifier(Modifier::DIM)
80 }
81
82 #[must_use]
84 pub fn error(self) -> Style {
85 self.fg(Color::Red)
86 }
87
88 #[must_use]
90 pub fn warn(self) -> Style {
91 self.fg(Color::Yellow)
92 }
93
94 #[must_use]
96 pub fn ok(self) -> Style {
97 self.fg(Color::Green)
98 }
99
100 #[must_use]
102 pub fn selection(self) -> Style {
103 Style::default().add_modifier(Modifier::REVERSED)
104 }
105
106 #[must_use]
109 pub fn tier(self, tier: TrustTier) -> Style {
110 match tier {
111 TrustTier::HumanReviewed => self.fg(Color::Green),
112 TrustTier::MachineConfirmed => self.fg(Color::Blue),
113 TrustTier::Unverified => self.fg(Color::DarkGray),
114 }
115 }
116
117 #[must_use]
119 pub fn actor(self, kind: ActorKind) -> Style {
120 match kind {
121 ActorKind::Human => self.fg(Color::Cyan),
122 ActorKind::Process => self.fg(Color::Magenta),
123 ActorKind::Agent => self.fg(Color::Blue),
124 ActorKind::Other => Style::default(),
125 }
126 }
127
128 #[must_use]
130 pub fn status(self, status: &Status) -> Style {
131 match status {
132 Status::Draft => self.fg(Color::Yellow),
133 Status::Deprecated => self.dim().add_modifier(Modifier::CROSSED_OUT),
134 Status::Stable | Status::Other(_) => Style::default(),
135 }
136 }
137}
138
139#[must_use]
142pub const fn tier_glyph(tier: TrustTier) -> &'static str {
143 match tier {
144 TrustTier::HumanReviewed => "◆",
145 TrustTier::MachineConfirmed => "●",
146 TrustTier::Unverified => "○",
147 }
148}
149
150#[must_use]
152pub const fn status_glyph(status: &Status) -> &'static str {
153 match status {
154 Status::Draft => "◐",
155 Status::Deprecated => "◌",
156 Status::Stable | Status::Other(_) => "●",
157 }
158}