tty_interface/
style.rs

1/// Colors to be used for foreground and background text formatting.
2#[derive(Debug, Copy, Clone, Eq, PartialEq)]
3pub enum Color {
4    Black,
5    DarkGrey,
6    Red,
7    DarkRed,
8    Green,
9    DarkGreen,
10    Yellow,
11    DarkYellow,
12    Blue,
13    DarkBlue,
14    Magenta,
15    DarkMagenta,
16    Cyan,
17    DarkCyan,
18    White,
19    Grey,
20    Reset,
21}
22
23impl Color {
24    /// Convert this to a style with this as the foreground color.
25    pub fn as_style(self) -> Style {
26        Style::new().set_foreground(self)
27    }
28}
29
30/// Text formatting styles.
31///
32/// # Examples
33/// ```
34/// use tty_interface::{Color, Style};
35///
36/// let style = Color::Red.as_style().set_bold(true);
37/// ```
38#[derive(Debug, Copy, Clone, Eq, PartialEq)]
39pub struct Style {
40    foreground_color: Option<Color>,
41    background_color: Option<Color>,
42    is_bold: bool,
43    is_italic: bool,
44    is_underline: bool,
45}
46
47impl Default for Style {
48    fn default() -> Self {
49        Self::new()
50    }
51}
52
53impl Style {
54    /// Create a new style with no colors or styling.
55    pub fn new() -> Self {
56        Self {
57            foreground_color: None,
58            background_color: None,
59            is_bold: false,
60            is_italic: false,
61            is_underline: false,
62        }
63    }
64
65    /// Create a new style with the specified foreground color.
66    pub fn set_foreground(&self, color: Color) -> Style {
67        Style {
68            foreground_color: Some(color),
69            ..*self
70        }
71    }
72
73    /// This style's foreground color, if specified.
74    pub fn foreground(&self) -> Option<Color> {
75        self.foreground_color
76    }
77
78    /// Create a new style with the specified background color.
79    pub fn set_background(&self, color: Color) -> Style {
80        Style {
81            background_color: Some(color),
82            ..*self
83        }
84    }
85
86    /// This style's background color, if specified.
87    pub fn background(&self) -> Option<Color> {
88        self.background_color
89    }
90
91    /// Create a new style with the specified bold value.
92    pub fn set_bold(&self, is_bold: bool) -> Style {
93        Style { is_bold, ..*self }
94    }
95
96    /// Whether this style is bolded.
97    pub fn is_bold(&self) -> bool {
98        self.is_bold
99    }
100
101    /// Create a new style with the specified italic value.
102    pub fn set_italic(&self, is_italic: bool) -> Style {
103        Style { is_italic, ..*self }
104    }
105
106    /// Whether this style is italicized.
107    pub fn is_italic(&self) -> bool {
108        self.is_italic
109    }
110
111    /// Create a new style with the specified underline value.
112    pub fn set_underline(&self, is_underline: bool) -> Style {
113        Style {
114            is_underline,
115            ..*self
116        }
117    }
118
119    /// Whether this style is underlined.
120    pub fn is_underlined(&self) -> bool {
121        self.is_underline
122    }
123}
124
125#[cfg(test)]
126mod tests {
127    use crate::{Color, Style};
128
129    #[test]
130    fn style_foreground() {
131        let mut style = Style::new();
132        assert_eq!(None, style.foreground());
133
134        style = style.set_foreground(Color::Blue);
135        assert_eq!(Some(Color::Blue), style.foreground());
136
137        style = style.set_foreground(Color::Red);
138        assert_eq!(Some(Color::Red), style.foreground());
139    }
140
141    #[test]
142    fn style_background() {
143        let mut style = Style::new();
144        assert_eq!(None, style.background());
145
146        style = style.set_background(Color::Yellow);
147        assert_eq!(Some(Color::Yellow), style.background());
148
149        style = style.set_background(Color::Magenta);
150        assert_eq!(Some(Color::Magenta), style.background());
151    }
152
153    #[test]
154    fn style_bold() {
155        let mut style = Style::new();
156        assert!(!style.is_bold());
157
158        style = style.set_bold(true);
159        assert!(style.is_bold());
160    }
161
162    #[test]
163    fn style_italic() {
164        let mut style = Style::new();
165        assert!(!style.is_italic());
166
167        style = style.set_italic(true);
168        assert!(style.is_italic());
169    }
170
171    #[test]
172    fn style_underline() {
173        let mut style = Style::new();
174        assert!(!style.is_underlined());
175
176        style = style.set_underline(true);
177        assert!(style.is_underlined());
178    }
179}