tabled/features/height/
cell_height_limit.rs

1use papergrid::{
2    records::{Records, RecordsMut},
3    util::get_lines,
4    width::CfgWidthFunction,
5    Entity,
6};
7
8use crate::{measurment::Measurment, peaker::Peaker, CellOption, Height, Table, TableOption};
9
10use super::table_height_limit::TableHeightLimit;
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::peaker::PriorityNone
17#[derive(Debug)]
18pub struct CellHeightLimit<W = usize> {
19    height: W,
20}
21
22impl<W> CellHeightLimit<W> {
23    /// Constructs a new object.
24    pub fn new(height: W) -> Self
25    where
26        W: Measurment<Height>,
27    {
28        Self { height }
29    }
30
31    /// Set's a priority by which the limit logic will be applied.
32    pub fn priority<P>(self) -> TableHeightLimit<W, P>
33    where
34        P: Peaker,
35        W: Measurment<Height>,
36    {
37        TableHeightLimit::new(self.height).priority::<P>()
38    }
39}
40
41impl<W, R> CellOption<R> for CellHeightLimit<W>
42where
43    W: Measurment<Height>,
44    R: Records + RecordsMut<String>,
45{
46    fn change_cell(&mut self, table: &mut Table<R>, entity: Entity) {
47        let height = self.height.measure(table.get_records(), table.get_config());
48
49        let (count_rows, count_cols) = table.shape();
50        for pos in entity.iter(count_rows, count_cols) {
51            let records = table.get_records();
52            let cell_height = records.count_lines(pos);
53            if cell_height <= height {
54                continue;
55            }
56
57            let content = records.get_text(pos);
58            let content = limit_lines(content, height);
59            let ctrl = CfgWidthFunction::from_cfg(table.get_config());
60            table.get_records_mut().set(pos, content, &ctrl);
61        }
62
63        table.destroy_height_cache();
64        table.destroy_width_cache();
65    }
66}
67
68impl<W, R> TableOption<R> for CellHeightLimit<W>
69where
70    W: Measurment<Height>,
71    R: Records,
72{
73    fn change(&mut self, table: &mut Table<R>) {
74        TableHeightLimit::new(self.height.measure(table.get_records(), table.get_config()))
75            .change(table)
76    }
77}
78
79fn limit_lines(s: &str, n: usize) -> String {
80    let mut text = String::new();
81    for (i, line) in get_lines(s).take(n).enumerate() {
82        if i > 0 {
83            text.push('\n');
84        }
85
86        text.push_str(&line);
87    }
88
89    text
90}