tabled/features/height/
table_height_limit.rs

1use papergrid::records::Records;
2
3use crate::{
4    measurment::Measurment,
5    peaker::{Peaker, PriorityNone},
6    Height, Table, TableOption,
7};
8
9use super::get_table_total_height2;
10
11/// A modification of a table to decrease the table height.
12#[derive(Debug)]
13pub struct TableHeightLimit<W = usize, P = PriorityNone> {
14    height: W,
15    priority: P,
16}
17
18impl<W> TableHeightLimit<W, PriorityNone> {
19    /// Creates a new object.
20    pub fn new(height: W) -> Self
21    where
22        W: Measurment<Height>,
23    {
24        Self {
25            height,
26            priority: PriorityNone::default(),
27        }
28    }
29
30    /// Sets a different priority logic.
31    pub fn priority<P>(self) -> TableHeightLimit<W, P>
32    where
33        P: Peaker,
34    {
35        TableHeightLimit {
36            priority: P::create(),
37            height: self.height,
38        }
39    }
40}
41
42impl<R, W, P> TableOption<R> for TableHeightLimit<W, P>
43where
44    R: Records,
45    W: Measurment<Height>,
46    P: Peaker + Clone,
47{
48    fn change(&mut self, table: &mut Table<R>) {
49        if table.is_empty() {
50            return;
51        }
52
53        let height = self.height.measure(table.get_records(), table.get_config());
54        let (total, heights) = get_table_total_height2(table.get_records(), table.get_config());
55        if total <= height {
56            return;
57        }
58
59        decrease_total_height(table, heights, total, height, self.priority.clone());
60    }
61}
62
63fn decrease_total_height<P, R>(
64    table: &mut Table<R>,
65    mut list: Vec<usize>,
66    total: usize,
67    expected: usize,
68    priority: P,
69) where
70    P: Peaker,
71    R: Records,
72{
73    decrease_list(&mut list, total, expected, priority);
74    table.cache_height(list);
75    table.destroy_width_cache();
76}
77
78fn decrease_list<P>(list: &mut [usize], total: usize, mut value: usize, mut peaker: P)
79where
80    P: Peaker,
81{
82    while value != total {
83        let p = peaker.peak(&[], list);
84        let row = match p {
85            Some(row) => row,
86            None => break,
87        };
88
89        list[row] -= 1;
90        value += 1;
91    }
92}