1use super::color::ThemeColor;
4
5#[derive(Clone, Debug, Default, PartialEq)]
10#[allow(clippy::struct_excessive_bools)] pub struct ThemeStyle {
12 pub fg: Option<ThemeColor>,
14 pub bg: Option<ThemeColor>,
16 pub bold: bool,
18 pub italic: bool,
20 pub underline: bool,
22 pub dim: bool,
24}
25
26impl ThemeStyle {
27 #[must_use]
29 pub const fn new() -> Self {
30 Self {
31 fg: None,
32 bg: None,
33 bold: false,
34 italic: false,
35 underline: false,
36 dim: false,
37 }
38 }
39
40 #[must_use]
42 pub const fn fg(color: ThemeColor) -> Self {
43 Self {
44 fg: Some(color),
45 bg: None,
46 bold: false,
47 italic: false,
48 underline: false,
49 dim: false,
50 }
51 }
52
53 #[must_use]
55 pub const fn bg(color: ThemeColor) -> Self {
56 Self {
57 fg: None,
58 bg: Some(color),
59 bold: false,
60 italic: false,
61 underline: false,
62 dim: false,
63 }
64 }
65
66 #[must_use]
68 pub const fn with_fg(mut self, color: ThemeColor) -> Self {
69 self.fg = Some(color);
70 self
71 }
72
73 #[must_use]
75 pub const fn with_bg(mut self, color: ThemeColor) -> Self {
76 self.bg = Some(color);
77 self
78 }
79
80 #[must_use]
82 pub const fn bold(mut self) -> Self {
83 self.bold = true;
84 self
85 }
86
87 #[must_use]
89 pub const fn italic(mut self) -> Self {
90 self.italic = true;
91 self
92 }
93
94 #[must_use]
96 pub const fn underline(mut self) -> Self {
97 self.underline = true;
98 self
99 }
100
101 #[must_use]
103 pub const fn dim(mut self) -> Self {
104 self.dim = true;
105 self
106 }
107
108 #[must_use]
111 pub fn merge(&self, other: &Self) -> Self {
112 Self {
113 fg: other.fg.or(self.fg),
114 bg: other.bg.or(self.bg),
115 bold: other.bold || self.bold,
116 italic: other.italic || self.italic,
117 underline: other.underline || self.underline,
118 dim: other.dim || self.dim,
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_style_builder() {
129 let style = ThemeStyle::fg(ThemeColor::new(255, 0, 0))
130 .with_bg(ThemeColor::new(0, 0, 0))
131 .bold();
132
133 assert_eq!(style.fg, Some(ThemeColor::new(255, 0, 0)));
134 assert_eq!(style.bg, Some(ThemeColor::new(0, 0, 0)));
135 assert!(style.bold);
136 assert!(!style.italic);
137 }
138
139 #[test]
140 fn test_style_merge() {
141 let base = ThemeStyle::fg(ThemeColor::new(255, 0, 0)).bold();
142 let overlay = ThemeStyle::bg(ThemeColor::new(0, 0, 0)).italic();
143
144 let merged = base.merge(&overlay);
145 assert_eq!(merged.fg, Some(ThemeColor::new(255, 0, 0)));
146 assert_eq!(merged.bg, Some(ThemeColor::new(0, 0, 0)));
147 assert!(merged.bold);
148 assert!(merged.italic);
149 }
150}