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