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 Style {
48    /// Create a new style with no colors or styling.
49    pub fn new() -> Self {
50        Self {
51            foreground_color: None,
52            background_color: None,
53            is_bold: false,
54            is_italic: false,
55            is_underline: false,
56        }
57    }
58
59    /// Create a new style with the specified foreground color.
60    pub fn set_foreground(&self, color: Color) -> Style {
61        Style {
62            foreground_color: Some(color),
63            ..*self
64        }
65    }
66
67    /// This style's foreground color, if specified.
68    pub fn foreground(&self) -> Option<Color> {
69        self.foreground_color
70    }
71
72    /// Create a new style with the specified background color.
73    pub fn set_background(&self, color: Color) -> Style {
74        Style {
75            background_color: Some(color),
76            ..*self
77        }
78    }
79
80    /// This style's background color, if specified.
81    pub fn background(&self) -> Option<Color> {
82        self.background_color
83    }
84
85    /// Create a new style with the specified bold value.
86    pub fn set_bold(&self, is_bold: bool) -> Style {
87        Style { is_bold, ..*self }
88    }
89
90    /// Whether this style is bolded.
91    pub fn is_bold(&self) -> bool {
92        self.is_bold
93    }
94
95    /// Create a new style with the specified italic value.
96    pub fn set_italic(&self, is_italic: bool) -> Style {
97        Style { is_italic, ..*self }
98    }
99
100    /// Whether this style is italicized.
101    pub fn is_italic(&self) -> bool {
102        self.is_italic
103    }
104
105    /// Create a new style with the specified underline value.
106    pub fn set_underline(&self, is_underline: bool) -> Style {
107        Style {
108            is_underline,
109            ..*self
110        }
111    }
112
113    /// Whether this style is underlined.
114    pub fn is_underlined(&self) -> bool {
115        self.is_underline
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use crate::{Color, Style};
122
123    #[test]
124    fn style_foreground() {
125        let mut style = Style::new();
126        assert_eq!(None, style.foreground());
127
128        style = style.set_foreground(Color::Blue);
129        assert_eq!(Some(Color::Blue), style.foreground());
130
131        style = style.set_foreground(Color::Red);
132        assert_eq!(Some(Color::Red), style.foreground());
133    }
134
135    #[test]
136    fn style_background() {
137        let mut style = Style::new();
138        assert_eq!(None, style.background());
139
140        style = style.set_background(Color::Yellow);
141        assert_eq!(Some(Color::Yellow), style.background());
142
143        style = style.set_background(Color::Magenta);
144        assert_eq!(Some(Color::Magenta), style.background());
145    }
146
147    #[test]
148    fn style_bold() {
149        let mut style = Style::new();
150        assert_eq!(false, style.is_bold());
151
152        style = style.set_bold(true);
153        assert_eq!(true, style.is_bold());
154    }
155
156    #[test]
157    fn style_italic() {
158        let mut style = Style::new();
159        assert_eq!(false, style.is_italic());
160
161        style = style.set_italic(true);
162        assert_eq!(true, style.is_italic());
163    }
164
165    #[test]
166    fn style_underline() {
167        let mut style = Style::new();
168        assert_eq!(false, style.is_underlined());
169
170        style = style.set_underline(true);
171        assert_eq!(true, style.is_underlined());
172    }
173}