1 | use crate::{ |
2 | grid::{ |
3 | config::{ColoredConfig, Entity}, |
4 | dimension::CompleteDimensionVecRecords, |
5 | records::{ExactRecords, IntoRecords, PeekableRecords, Records}, |
6 | }, |
7 | settings::{ |
8 | measurement::Measurement, |
9 | peaker::{Peaker, PriorityNone}, |
10 | Height, TableOption, |
11 | }, |
12 | }; |
13 | |
14 | use super::util::get_table_height; |
15 | |
16 | /// A modification of a table to increase the table height. |
17 | #[derive (Debug, Clone)] |
18 | pub struct TableHeightIncrease<W = usize, P = PriorityNone> { |
19 | height: W, |
20 | priority: P, |
21 | } |
22 | |
23 | impl<W> TableHeightIncrease<W, PriorityNone> { |
24 | /// Creates a new object. |
25 | pub fn new(height: W) -> Self |
26 | where |
27 | W: Measurement<Height>, |
28 | { |
29 | Self { |
30 | height, |
31 | priority: PriorityNone::default(), |
32 | } |
33 | } |
34 | |
35 | /// Sets a different priority logic. |
36 | pub fn priority<P>(self) -> TableHeightIncrease<W, P> |
37 | where |
38 | P: Peaker, |
39 | { |
40 | TableHeightIncrease { |
41 | priority: P::create(), |
42 | height: self.height, |
43 | } |
44 | } |
45 | } |
46 | |
47 | impl<R, W, P> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> |
48 | for TableHeightIncrease<W, P> |
49 | where |
50 | W: Measurement<Height>, |
51 | P: Peaker + Clone, |
52 | R: Records + ExactRecords + PeekableRecords, |
53 | for<'a> &'a R: Records, |
54 | for<'a> <<&'a R as Records>::Iter as IntoRecords>::Cell: AsRef<str>, |
55 | { |
56 | fn change( |
57 | self, |
58 | records: &mut R, |
59 | cfg: &mut ColoredConfig, |
60 | dims: &mut CompleteDimensionVecRecords<'_>, |
61 | ) { |
62 | if records.count_rows() == 0 || records.count_columns() == 0 { |
63 | return; |
64 | } |
65 | |
66 | let height = self.height.measure(&*records, cfg); |
67 | let (total, mut heights) = get_table_height(&*records, cfg); |
68 | if total >= height { |
69 | return; |
70 | } |
71 | |
72 | get_increase_list(&mut heights, height, total, self.priority); |
73 | |
74 | dims.set_heights(heights); |
75 | } |
76 | |
77 | fn hint_change(&self) -> Option<Entity> { |
78 | Some(Entity::Row(0)) |
79 | } |
80 | } |
81 | |
82 | fn get_increase_list<P>(list: &mut [usize], total: usize, mut current: usize, mut peaker: P) |
83 | where |
84 | P: Peaker, |
85 | { |
86 | while current != total { |
87 | let col: usize = match peaker.peak(&[], widths:list) { |
88 | Some(col: usize) => col, |
89 | None => break, |
90 | }; |
91 | |
92 | list[col] += 1; |
93 | current += 1; |
94 | } |
95 | } |
96 | |