1use crate::{
2 grid::config::{ColoredConfig, Entity, Position, SpannedConfig},
3 grid::records::{ExactRecords, Records},
4 settings::CellOption,
5};
6
7use 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)]
35pub struct BorderChar {
36 c: char,
37 offset: Offset,
38 horizontal: bool,
39}
40
41impl 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
61impl<R> CellOption<R, ColoredConfig> for BorderChar
62where
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
75fn 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
88fn 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