tabled/features/style/
raw_style.rs
1use std::collections::HashMap;
5
6use papergrid::{records::Records, Borders};
7
8use crate::{
9 style::{HorizontalLine, Line, VerticalLine},
10 Border, Style, Table, TableOption,
11};
12
13#[derive(Default, Debug, Clone)]
17pub struct RawStyle {
18 borders: Borders<char>,
19 horizontals: HashMap<usize, Line>,
20 verticals: HashMap<usize, Line>,
21}
22
23impl RawStyle {
24 pub fn set_top(&mut self, s: Option<char>) -> &mut Self {
26 self.borders.top = s;
27 self
28 }
29
30 pub fn set_bottom(&mut self, s: Option<char>) -> &mut Self {
32 self.borders.bottom = s;
33 self
34 }
35
36 pub fn set_left(&mut self, s: Option<char>) -> &mut Self {
38 self.borders.vertical_left = s;
39 self
40 }
41
42 pub fn set_right(&mut self, s: Option<char>) -> &mut Self {
44 self.borders.vertical_right = s;
45 self
46 }
47
48 pub fn set_top_split(&mut self, s: Option<char>) -> &mut Self {
50 self.borders.top_intersection = s;
51 self
52 }
53
54 pub fn set_bottom_split(&mut self, s: Option<char>) -> &mut Self {
56 self.borders.bottom_intersection = s;
57 self
58 }
59
60 pub fn set_left_split(&mut self, s: Option<char>) -> &mut Self {
62 self.borders.horizontal_left = s;
63 self
64 }
65
66 pub fn set_right_split(&mut self, s: Option<char>) -> &mut Self {
68 self.borders.horizontal_right = s;
69 self
70 }
71
72 pub fn set_internal_split(&mut self, s: Option<char>) -> &mut Self {
74 self.borders.intersection = s;
75 self
76 }
77
78 pub fn set_vertical(&mut self, s: Option<char>) -> &mut Self {
80 self.borders.vertical = s;
81 self
82 }
83
84 pub fn set_horizontal(&mut self, s: Option<char>) -> &mut Self {
86 self.borders.horizontal = s;
87 self
88 }
89
90 pub fn set_top_left(&mut self, s: Option<char>) -> &mut Self {
92 self.borders.top_left = s;
93 self
94 }
95
96 pub fn set_top_right(&mut self, s: Option<char>) -> &mut Self {
98 self.borders.top_right = s;
99 self
100 }
101
102 pub fn set_bottom_left(&mut self, s: Option<char>) -> &mut Self {
104 self.borders.bottom_left = s;
105 self
106 }
107
108 pub fn set_bottom_right(&mut self, s: Option<char>) -> &mut Self {
110 self.borders.bottom_right = s;
111 self
112 }
113
114 pub fn set_horizontals(&mut self, lines: HashMap<usize, Line>) -> &mut Self {
148 self.horizontals = lines;
149 self
150 }
151
152 pub fn set_verticals(&mut self, lines: HashMap<usize, Line>) -> &mut Self {
186 self.verticals = lines;
187 self
188 }
189
190 pub fn get_left(&self) -> Option<char> {
192 self.borders.vertical_left
193 }
194
195 pub fn get_left_intersection(&self) -> Option<char> {
197 self.borders.horizontal_left
198 }
199
200 pub fn get_right(&self) -> Option<char> {
202 self.borders.vertical_right
203 }
204
205 pub fn get_right_intersection(&self) -> Option<char> {
207 self.borders.horizontal_right
208 }
209
210 pub fn get_top(&self) -> Option<char> {
212 self.borders.top
213 }
214
215 pub fn get_top_left(&self) -> Option<char> {
217 self.borders.top_left
218 }
219
220 pub fn get_top_right(&self) -> Option<char> {
222 self.borders.top_right
223 }
224
225 pub fn get_top_intersection(&self) -> Option<char> {
227 self.borders.top_intersection
228 }
229
230 pub fn get_bottom(&self) -> Option<char> {
232 self.borders.bottom
233 }
234
235 pub fn get_bottom_left(&self) -> Option<char> {
237 self.borders.bottom_left
238 }
239
240 pub fn get_bottom_right(&self) -> Option<char> {
242 self.borders.bottom_right
243 }
244
245 pub fn get_bottom_intersection(&self) -> Option<char> {
247 self.borders.bottom_intersection
248 }
249
250 pub fn get_frame(&self) -> Border {
252 Border::new_raw(Some(papergrid::Border {
253 top: self.borders.top,
254 bottom: self.borders.bottom,
255 left: self.borders.vertical_left,
256 right: self.borders.vertical_right,
257 left_top_corner: self.borders.top_left,
258 right_top_corner: self.borders.top_right,
259 left_bottom_corner: self.borders.bottom_left,
260 right_bottom_corner: self.borders.bottom_right,
261 }))
262 }
263
264 #[cfg_attr(docsrs, doc(cfg(feature = "color")))]
266 #[cfg(feature = "color")]
267 pub fn colored(self) -> crate::style::RawStyleColored {
268 crate::style::RawStyleColored::from(self)
269 }
270}
271
272impl From<Borders<char>> for RawStyle {
273 fn from(borders: Borders<char>) -> Self {
274 Self {
275 borders,
276 horizontals: HashMap::new(),
277 verticals: HashMap::new(),
278 }
279 }
280}
281
282impl<R> TableOption<R> for RawStyle
283where
284 R: Records,
285{
286 fn change(&mut self, table: &mut Table<R>) {
287 (&*self).change(table)
288 }
289}
290
291impl<R> TableOption<R> for &RawStyle
292where
293 R: Records,
294{
295 fn change(&mut self, table: &mut Table<R>) {
296 if table.is_empty() {
297 return;
298 }
299
300 let (count_rows, count_cols) = table.shape();
301
302 let cfg = table.get_config_mut();
303 cfg.clear_theme();
304 cfg.set_borders(self.borders.clone());
305
306 if count_rows > 1 {
307 for (&row, line) in &self.horizontals {
308 if line.is_empty() {
309 cfg.remove_horizontal_line(row);
310 } else {
311 cfg.set_horizontal_line(row, papergrid::HorizontalLine::from(*line));
312 }
313 }
314 }
315
316 if count_cols > 1 {
317 for (&col, line) in &self.verticals {
318 if line.is_empty() {
319 cfg.remove_vertical_line(col);
320 } else {
321 cfg.set_vertical_line(col, papergrid::VerticalLine::from(*line));
322 }
323 }
324 }
325
326 table.destroy_width_cache();
327 table.destroy_height_cache();
328 }
329}
330
331impl<T, B, L, R, H, V, HLines, VLines> From<Style<T, B, L, R, H, V, HLines, VLines>> for RawStyle
332where
333 HLines: IntoIterator<Item = HorizontalLine>,
334 VLines: IntoIterator<Item = VerticalLine>,
335{
336 fn from(style: Style<T, B, L, R, H, V, HLines, VLines>) -> Self {
337 let horizontals = style
338 .horizontals
339 .into_iter()
340 .flat_map(|hr| {
341 let index = hr.index;
342 hr.line.map(|line| (index, line))
343 })
344 .collect();
345
346 let verticals = style
347 .verticals
348 .into_iter()
349 .flat_map(|hr| {
350 let index = hr.index;
351 hr.line.map(|line| (index, line))
352 })
353 .collect();
354
355 Self {
356 borders: style.borders,
357 horizontals,
358 verticals,
359 }
360 }
361}