1 | use crate::{ |
2 | grid::config::{ColoredConfig, Entity, Position, SpannedConfig}, |
3 | grid::records::{ExactRecords, Records}, |
4 | settings::CellOption, |
5 | }; |
6 | |
7 | use super::Offset; |
8 | |
9 | /// [`BorderChar`] sets a char to a specific location on a horizontal line. |
10 | /// |
11 | /// # Example |
12 | /// |
13 | /// ```rust |
14 | /// use tabled::{Table, settings::{style::{Style, BorderChar, Offset}, Modify, object::{Object, Rows, Columns}}}; |
15 | /// |
16 | /// let mut table = Table::new(["Hello World" ]); |
17 | /// table |
18 | /// .with(Style::markdown()) |
19 | /// .with(Modify::new(Rows::single(1)) |
20 | /// .with(BorderChar::horizontal(':' , Offset::Begin(0))) |
21 | /// .with(BorderChar::horizontal(':' , Offset::End(0))) |
22 | /// ) |
23 | /// .with(Modify::new((1, 0).and((1, 1))).with(BorderChar::vertical('#' , Offset::Begin(0)))); |
24 | /// |
25 | /// assert_eq!( |
26 | /// table.to_string(), |
27 | /// concat!( |
28 | /// "| &str | \n" , |
29 | /// "|:-----------:| \n" , |
30 | /// "# Hello World #" , |
31 | /// ), |
32 | /// ); |
33 | /// ``` |
34 | #[derive (Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] |
35 | pub struct BorderChar { |
36 | c: char, |
37 | offset: Offset, |
38 | horizontal: bool, |
39 | } |
40 | |
41 | impl BorderChar { |
42 | /// Creates a [`BorderChar`] which overrides horizontal line. |
43 | pub fn horizontal(c: char, offset: Offset) -> Self { |
44 | Self { |
45 | c, |
46 | offset, |
47 | horizontal: true, |
48 | } |
49 | } |
50 | |
51 | /// Creates a [`BorderChar`] which overrides vertical line. |
52 | pub fn vertical(c: char, offset: Offset) -> Self { |
53 | Self { |
54 | c, |
55 | offset, |
56 | horizontal: false, |
57 | } |
58 | } |
59 | } |
60 | |
61 | impl<R> CellOption<R, ColoredConfig> for BorderChar |
62 | where |
63 | R: Records + ExactRecords, |
64 | { |
65 | fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) { |
66 | let cells: EntityIterator = entity.iter(records.count_rows(), count_cols:records.count_columns()); |
67 | |
68 | match self.horizontal { |
69 | true => add_char_horizontal(cfg, self.c, self.offset, cells), |
70 | false => add_char_vertical(cfg, self.c, self.offset, cells), |
71 | } |
72 | } |
73 | } |
74 | |
75 | fn add_char_vertical<I: Iterator<Item = Position>>( |
76 | cfg: &mut SpannedConfig, |
77 | c: char, |
78 | offset: Offset, |
79 | cells: I, |
80 | ) { |
81 | let offset: Offset = offset.into(); |
82 | |
83 | for pos: (usize, usize) in cells { |
84 | cfg.set_vertical_char(pos, c, offset); |
85 | } |
86 | } |
87 | |
88 | fn add_char_horizontal<I: Iterator<Item = Position>>( |
89 | cfg: &mut SpannedConfig, |
90 | c: char, |
91 | offset: Offset, |
92 | cells: I, |
93 | ) { |
94 | let offset: Offset = offset.into(); |
95 | |
96 | for pos: (usize, usize) in cells { |
97 | cfg.set_horizontal_char(pos, c, offset); |
98 | } |
99 | } |
100 | |