libtableformat/content/
content_style.rs1use colored::Color;
2
3#[derive(Debug, Clone)]
4pub enum CellWidth {
5 Fixed(usize),
7 Minimum(usize),
9 Content,
11}
12
13impl CellWidth {
14 pub fn default() -> CellWidth {
15 CellWidth::Content
16 }
17}
18
19#[derive(Debug, Clone)]
21#[derive(PartialEq)]
22pub enum Alignment {
23 Left,
24 Center,
25 Right
26}
27
28impl Alignment {
29 fn from_token(token: char) -> Option<Alignment> {
30 match token {
31 '<' => Some(Alignment::Left),
32 '^' => Some(Alignment::Center),
33 '>' => Some(Alignment::Right),
34 _ => None
35 }
36 }
37}
38
39#[derive(Debug, Clone)]
41pub enum Wrap {
42 Truncate,
44 Wrap
46}
47
48impl Wrap {
49 fn from_token(token: char) -> Option<Wrap> {
50 match token {
51 ';' => Some(Wrap::Wrap),
52 '.' => Some(Wrap::Truncate),
53 _ => None
54 }
55 }
56}
57
58#[allow(unused_macros)]
59#[macro_export]
60macro_rules! content_style {
61 ( $style:literal ) => {
62 ContentStyle::from_format($style)
63 }
64}
65
66#[derive(Debug, Clone)]
68pub struct ContentStyle {
69 pub foreground_color: Option<Color>,
70 pub background_color: Option<Color>,
71 pub alignment: Alignment,
72 pub wrap: Wrap,
73 pub width: CellWidth
74}
75
76impl ContentStyle {
77 #[must_use]
78 pub fn default() -> ContentStyle {
79 ContentStyle {
80 foreground_color: None,
81 background_color: None,
82 alignment: Alignment::Left,
83 wrap: Wrap::Truncate,
84 width: CellWidth::Content,
85 }
86 }
87
88 #[must_use]
89 pub fn new(
90 foreground_color: Option<Color>,
91 background_color: Option<Color>,
92 alignment: Alignment,
93 wrap: Wrap,
94 width: CellWidth
95 ) -> ContentStyle {
96 ContentStyle {
97 foreground_color,
98 background_color,
99 alignment,
100 wrap,
101 width,
102 }
103 }
104
105 #[must_use]
115 pub fn from_format(format: &str) -> ContentStyle {
116 let mut style = ContentStyle::default();
118
119 let tokens: Vec<char> = format[1..format.len() - 1].chars().collect();
121 let mut token_ix = 0;
122 while token_ix < tokens.len() {
123 let token = tokens[token_ix];
124
125 if let Some(color) = ContentStyle::color_from_token(token) {
127 style.foreground_color = Some(color)
128 }
129 if let Some(alignment) = Alignment::from_token(token) {
131 style.alignment = alignment
132 }
133 if let Some(wrap) = Wrap::from_token(token) {
135 style.wrap = wrap
136 }
137
138 if token == '-' {
140 if tokens.len() > token_ix + 1 {
142 style.background_color =
143 ContentStyle::color_from_token(tokens[token_ix + 1]);
144 token_ix += 1;
146 }
147 }
148 token_ix += 1;
149
150 if token == ':' {
152 if let Some(ix) = format[token_ix+1..=tokens.len()].find(':') {
154 let width = format[token_ix+1..=token_ix+ix].parse::<usize>().unwrap();
155 style.width = CellWidth::Fixed(width);
156 token_ix += ix + 1;
157 }
158 }
159
160 if token == '|' {
162 if let Some(ix) = format[token_ix+1..=tokens.len()].find('|') {
165 let width = format[token_ix+1..=token_ix+ix].parse::<usize>().unwrap();
166 style.width = CellWidth::Minimum(width);
167 token_ix += ix + 1;
168 }
169 }
170 }
171
172 style
173 }
174
175 fn color_from_token(
176 token: char
177 ) -> Option<Color> {
178 match token {
179 'w' => Some(Color::White),
180 'l' => Some(Color::Black),
181 'r' => Some(Color::Red),
182 'g' => Some(Color::Green),
183 'y' => Some(Color::Yellow),
184 'b' => Some(Color::Blue),
185 'm' => Some(Color::Magenta),
186 'c' => Some(Color::Cyan),
187 'W' => Some(Color::BrightWhite),
188 'L' => Some(Color::BrightBlack),
189 'R' => Some(Color::BrightRed),
190 'G' => Some(Color::BrightGreen),
191 'Y' => Some(Color::BrightYellow),
192 'B' => Some(Color::BrightBlue),
193 'M' => Some(Color::BrightMagenta),
194 'C' => Some(Color::BrightCyan),
195 _ => None,
196 }
197 }
198}
199
200#[cfg(test)]
201mod tests {
202 use super::*;
203 use colored::Color;
204
205 #[test]
206 fn from_format_fixed_width() {
207 let style = ContentStyle::from_format("{c^;:15:}");
208
209 let expected =
210 ContentStyle {
211 foreground_color: Some(Color::Cyan),
212 background_color: None,
213 alignment: Alignment::Center,
214 wrap: Wrap::Wrap,
215 width: CellWidth::Fixed(15)
216 };
217
218 assert_eq!(
219 format!("{:?}", style),
220 format!("{:?}", expected)
221 );
222 }
223
224}