tabled/settings/style/
line_char.rs

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