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 | /// [`LineChar`] sets a char to a specific location on a horizontal line. |
10 | /// |
11 | /// # Example |
12 | /// |
13 | /// ```rust |
14 | /// use tabled::{Table, settings::{style::{Style, LineChar, 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(LineChar::horizontal(':' , Offset::Begin(0))) |
21 | /// .with(LineChar::horizontal(':' , Offset::End(0))) |
22 | /// ) |
23 | /// .with(Modify::new((1, 0).and((1, 1))).with(LineChar::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 LineChar { |
36 | c: char, |
37 | offset: Offset, |
38 | horizontal: bool, |
39 | } |
40 | |
41 | impl LineChar { |
42 | /// Creates a [`LineChar`] which overrides horizontal line. |
43 | pub fn horizontal(c: char, offset: impl Into<Offset>) -> Self { |
44 | let offset = offset.into(); |
45 | let horizontal = true; |
46 | |
47 | Self { |
48 | c, |
49 | offset, |
50 | horizontal, |
51 | } |
52 | } |
53 | |
54 | /// Creates a [`LineChar`] which overrides vertical line. |
55 | pub fn vertical(c: char, offset: impl Into<Offset>) -> Self { |
56 | let offset = offset.into(); |
57 | let horizontal = false; |
58 | |
59 | Self { |
60 | c, |
61 | offset, |
62 | horizontal, |
63 | } |
64 | } |
65 | } |
66 | |
67 | impl<R> CellOption<R, ColoredConfig> for LineChar |
68 | where |
69 | R: Records + ExactRecords, |
70 | { |
71 | fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) { |
72 | let cells: EntityIterator = entity.iter(records.count_rows(), count_cols:records.count_columns()); |
73 | |
74 | match self.horizontal { |
75 | true => add_char_horizontal(cfg, self.c, self.offset, cells), |
76 | false => add_char_vertical(cfg, self.c, self.offset, cells), |
77 | } |
78 | } |
79 | } |
80 | |
81 | fn add_char_vertical<I: Iterator<Item = Position>>( |
82 | cfg: &mut SpannedConfig, |
83 | c: char, |
84 | offset: Offset, |
85 | cells: I, |
86 | ) { |
87 | let offset: Offset = offset.into(); |
88 | |
89 | for pos: (usize, usize) in cells { |
90 | cfg.set_vertical_char(pos, c, offset); |
91 | } |
92 | } |
93 | |
94 | fn add_char_horizontal<I: Iterator<Item = Position>>( |
95 | cfg: &mut SpannedConfig, |
96 | c: char, |
97 | offset: Offset, |
98 | cells: I, |
99 | ) { |
100 | let offset: Offset = offset.into(); |
101 | |
102 | for pos: (usize, usize) in cells { |
103 | cfg.set_horizontal_char(pos, c, offset); |
104 | } |
105 | } |
106 | |