tabled/features/
measurment.rs
1use papergrid::{
4 height::HeightEstimator,
5 records::Records,
6 width::{CfgWidthFunction, WidthFunc},
7 GridConfig,
8};
9
10use crate::{height::get_table_total_height, width::get_table_widths_with_total, Height, Width};
11
12pub trait Measurment<Attribute> {
16 fn measure<R>(&self, records: R, cfg: &GridConfig) -> usize
18 where
19 R: Records;
20}
21
22impl<T> Measurment<T> for usize {
23 fn measure<R>(&self, _: R, _: &GridConfig) -> usize {
24 *self
25 }
26}
27
28#[derive(Debug)]
30pub struct Max;
31
32impl Measurment<Width> for Max {
33 fn measure<R>(&self, records: R, cfg: &GridConfig) -> usize
34 where
35 R: Records,
36 {
37 let ctrl = CfgWidthFunction::from_cfg(cfg);
38 grid_widths(&records, &ctrl)
39 .map(|r| r.max().unwrap_or(0))
40 .max()
41 .unwrap_or(0)
42 }
43}
44
45impl Measurment<Height> for Max {
46 fn measure<R>(&self, records: R, _: &GridConfig) -> usize
47 where
48 R: Records,
49 {
50 records_heights(&records)
51 .map(|r| r.max().unwrap_or(0))
52 .max()
53 .unwrap_or(0)
54 }
55}
56
57#[derive(Debug)]
59pub struct Min;
60
61impl Measurment<Width> for Min {
62 fn measure<R>(&self, records: R, cfg: &GridConfig) -> usize
63 where
64 R: Records,
65 {
66 let ctrl = CfgWidthFunction::from_cfg(cfg);
67 grid_widths(&records, &ctrl)
68 .map(|r| r.min().unwrap_or(0))
69 .max()
70 .unwrap_or(0)
71 }
72}
73
74impl Measurment<Height> for Min {
75 fn measure<R>(&self, records: R, _: &GridConfig) -> usize
76 where
77 R: Records,
78 {
79 records_heights(&records)
80 .map(|r| r.max().unwrap_or(0))
81 .min()
82 .unwrap_or(0)
83 }
84}
85
86#[derive(Debug)]
88pub struct Percent(pub usize);
89
90impl Measurment<Width> for Percent {
91 fn measure<R>(&self, records: R, cfg: &GridConfig) -> usize
92 where
93 R: Records,
94 {
95 let (_, total) = get_table_widths_with_total(&records, cfg);
96 (total * self.0) / 100
97 }
98}
99
100impl Measurment<Height> for Percent {
101 fn measure<R>(&self, records: R, cfg: &GridConfig) -> usize
102 where
103 R: Records,
104 {
105 let total = get_table_total_height(&records, cfg, &HeightEstimator::default());
106 (total * self.0) / 100
107 }
108}
109
110fn records_heights<R>(records: &R) -> impl Iterator<Item = impl Iterator<Item = usize> + '_> + '_
111where
112 R: Records,
113{
114 (0..records.count_rows()).map(move |row| {
115 (0..records.count_columns()).map(move |col| records.count_lines((row, col)))
116 })
117}
118
119fn grid_widths<'a, R, W>(
120 records: &'a R,
121 ctrl: &'a W,
122) -> impl Iterator<Item = impl Iterator<Item = usize> + 'a> + 'a
123where
124 W: WidthFunc,
125 R: Records,
126{
127 let (count_rows, count_cols) = (records.count_rows(), records.count_columns());
128 (0..count_rows)
129 .map(move |row| (0..count_cols).map(move |col| records.get_width((row, col), ctrl)))
130}