1use crate::{
2 grid::config::ColoredConfig,
3 grid::config::Entity,
4 grid::dimension::CompleteDimensionVecRecords,
5 grid::records::{ExactRecords, PeekableRecords, Records, RecordsMut},
6 grid::util::string::count_lines,
7 settings::{measurement::Measurement, peaker::Peaker, CellOption, Height, TableOption},
8};
9
10use super::TableHeightIncrease;
11
12/// A modification for cell/table to increase its height.
13///
14/// If used for a [`Table`] [`PriorityNone`] is used.
15///
16/// [`PriorityNone`]: crate::settings::peaker::PriorityNone
17/// [`Table`]: crate::Table
18#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
19pub struct CellHeightIncrease<W = usize> {
20 height: W,
21}
22
23impl<W> CellHeightIncrease<W> {
24 /// Creates a new object of the structure.
25 pub fn new(height: W) -> Self
26 where
27 W: Measurement<Height>,
28 {
29 Self { height }
30 }
31
32 /// The priority makes scence only for table, so the function
33 /// converts it to [`TableHeightIncrease`] with a given priority.
34 pub fn priority<P>(self) -> TableHeightIncrease<W, P>
35 where
36 P: Peaker,
37 W: Measurement<Height>,
38 {
39 TableHeightIncrease::new(self.height).priority::<P>()
40 }
41}
42
43impl<W, R> CellOption<R, ColoredConfig> for CellHeightIncrease<W>
44where
45 W: Measurement<Height>,
46 R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
47 for<'a> &'a R: Records,
48{
49 fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
50 let height = self.height.measure(&*records, cfg);
51
52 let count_rows = records.count_rows();
53 let count_columns = records.count_columns();
54
55 for pos in entity.iter(count_rows, count_columns) {
56 let is_valid_pos = pos.0 < count_rows && pos.1 < count_columns;
57 if !is_valid_pos {
58 continue;
59 }
60
61 let text = records.get_text(pos);
62
63 let cell_height = count_lines(text);
64 if cell_height >= height {
65 continue;
66 }
67
68 let content = add_lines(text, height - cell_height);
69 records.set(pos, content);
70 }
71 }
72}
73
74impl<R, W> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig>
75 for CellHeightIncrease<W>
76where
77 W: Measurement<Height>,
78 R: Records + ExactRecords + PeekableRecords,
79 for<'a> &'a R: Records,
80{
81 fn change(
82 self,
83 records: &mut R,
84 cfg: &mut ColoredConfig,
85 dims: &mut CompleteDimensionVecRecords<'static>,
86 ) {
87 let height: usize = self.height.measure(&*records, cfg);
88 TableHeightIncrease::new(height).change(records, cfg, dimension:dims)
89 }
90}
91
92fn add_lines(s: &str, n: usize) -> String {
93 let mut text: String = String::with_capacity(s.len() + n);
94 text.push_str(string:s);
95 text.extend(iter:std::iter::repeat(elt:'\n').take(n));
96
97 text
98}
99