1 use crate::style::{Color, Colored};
2 
3 /// Represents, optionally, a foreground and/or a background color.
4 ///
5 /// It can be applied using the `SetColors` command.
6 ///
7 /// It can also be created from a [Colored](enum.Colored.html) value or a tuple of
8 /// `(Color, Color)` in the order `(foreground, background)`.
9 ///
10 /// The [then](#method.then) method can be used to combine `Colors` values.
11 ///
12 /// For example:
13 /// ```no_run
14 /// use crossterm::style::{Color, Colors, Colored};
15 ///
16 /// // An example color, loaded from a config, file in ANSI format.
17 /// let config_color = "38;2;23;147;209";
18 ///
19 /// // Default to green text on a black background.
20 /// let default_colors = Colors::new(Color::Green, Color::Black);
21 /// // Load a colored value from a config and override the default colors
22 /// let colors = match Colored::parse_ansi(config_color) {
23 ///     Some(colored) => default_colors.then(&colored.into()),
24 ///     None => default_colors,
25 /// };
26 /// ```
27 ///
28 /// See [Color](enum.Color.html).
29 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
30 pub struct Colors {
31     pub foreground: Option<Color>,
32     pub background: Option<Color>,
33 }
34 
35 impl Colors {
36     /// Returns a new `Color` which, when applied, has the same effect as applying `self` and *then*
37     /// `other`.
then(&self, other: &Colors) -> Colors38     pub fn then(&self, other: &Colors) -> Colors {
39         Colors {
40             foreground: other.foreground.or(self.foreground),
41             background: other.background.or(self.background),
42         }
43     }
44 }
45 
46 impl Colors {
new(foreground: Color, background: Color) -> Colors47     pub fn new(foreground: Color, background: Color) -> Colors {
48         Colors {
49             foreground: Some(foreground),
50             background: Some(background),
51         }
52     }
53 }
54 
55 impl From<Colored> for Colors {
from(colored: Colored) -> Colors56     fn from(colored: Colored) -> Colors {
57         match colored {
58             Colored::ForegroundColor(color) => Colors {
59                 foreground: Some(color),
60                 background: None,
61             },
62             Colored::BackgroundColor(color) => Colors {
63                 foreground: None,
64                 background: Some(color),
65             },
66         }
67     }
68 }
69 
70 #[cfg(test)]
71 mod tests {
72     use crate::style::{Color, Colors};
73 
74     #[test]
test_colors_then()75     fn test_colors_then() {
76         use Color::*;
77 
78         assert_eq!(
79             Colors {
80                 foreground: None,
81                 background: None,
82             }
83             .then(&Colors {
84                 foreground: None,
85                 background: None,
86             }),
87             Colors {
88                 foreground: None,
89                 background: None,
90             }
91         );
92 
93         assert_eq!(
94             Colors {
95                 foreground: None,
96                 background: None,
97             }
98             .then(&Colors {
99                 foreground: Some(Black),
100                 background: None,
101             }),
102             Colors {
103                 foreground: Some(Black),
104                 background: None,
105             }
106         );
107 
108         assert_eq!(
109             Colors {
110                 foreground: None,
111                 background: None,
112             }
113             .then(&Colors {
114                 foreground: None,
115                 background: Some(Grey),
116             }),
117             Colors {
118                 foreground: None,
119                 background: Some(Grey),
120             }
121         );
122 
123         assert_eq!(
124             Colors {
125                 foreground: None,
126                 background: None,
127             }
128             .then(&Colors::new(White, Grey)),
129             Colors::new(White, Grey),
130         );
131 
132         assert_eq!(
133             Colors {
134                 foreground: None,
135                 background: Some(Blue),
136             }
137             .then(&Colors::new(White, Grey)),
138             Colors::new(White, Grey),
139         );
140 
141         assert_eq!(
142             Colors {
143                 foreground: Some(Blue),
144                 background: None,
145             }
146             .then(&Colors::new(White, Grey)),
147             Colors::new(White, Grey),
148         );
149 
150         assert_eq!(
151             Colors::new(Blue, Green).then(&Colors::new(White, Grey)),
152             Colors::new(White, Grey),
153         );
154 
155         assert_eq!(
156             Colors {
157                 foreground: Some(Blue),
158                 background: Some(Green),
159             }
160             .then(&Colors {
161                 foreground: None,
162                 background: Some(Grey),
163             }),
164             Colors {
165                 foreground: Some(Blue),
166                 background: Some(Grey),
167             }
168         );
169 
170         assert_eq!(
171             Colors {
172                 foreground: Some(Blue),
173                 background: Some(Green),
174             }
175             .then(&Colors {
176                 foreground: Some(White),
177                 background: None,
178             }),
179             Colors {
180                 foreground: Some(White),
181                 background: Some(Green),
182             }
183         );
184 
185         assert_eq!(
186             Colors {
187                 foreground: Some(Blue),
188                 background: Some(Green),
189             }
190             .then(&Colors {
191                 foreground: None,
192                 background: None,
193             }),
194             Colors {
195                 foreground: Some(Blue),
196                 background: Some(Green),
197             }
198         );
199 
200         assert_eq!(
201             Colors {
202                 foreground: None,
203                 background: Some(Green),
204             }
205             .then(&Colors {
206                 foreground: None,
207                 background: None,
208             }),
209             Colors {
210                 foreground: None,
211                 background: Some(Green),
212             }
213         );
214 
215         assert_eq!(
216             Colors {
217                 foreground: Some(Blue),
218                 background: None,
219             }
220             .then(&Colors {
221                 foreground: None,
222                 background: None,
223             }),
224             Colors {
225                 foreground: Some(Blue),
226                 background: None,
227             }
228         );
229     }
230 }
231