tabled/features/height/mod.rs
1//! The module contains [`Height`] structure which is responsible for a table and cell height.
2
3use papergrid::{height::HeightEstimator, records::Records, Estimate, GridConfig};
4
5use crate::measurment::Measurment;
6
7mod cell_height_increase;
8mod cell_height_limit;
9mod height_list;
10mod table_height_increase;
11mod table_height_limit;
12
13pub use cell_height_increase::CellHeightIncrease;
14pub use cell_height_limit::CellHeightLimit;
15pub use height_list::HeightList;
16pub use table_height_increase::TableHeightIncrease;
17pub use table_height_limit::TableHeightLimit;
18
19/// Height is a abstract factory for height settings.
20///
21/// # Example
22///
23/// ```
24/// use tabled::{Table, Height};
25///
26/// let data = vec![
27/// ("Some data", "here", "and here"),
28/// ("Some data on a next", "line", "right here"),
29/// ];
30///
31/// let table = Table::new(data)
32/// .with(Height::increase(10))
33/// .with(Height::limit(10))
34/// .to_string();
35///
36/// assert_eq!(
37/// table,
38/// "+---------------------+------+------------+\n\
39/// | &str | &str | &str |\n\
40/// | | | |\n\
41/// +---------------------+------+------------+\n\
42/// | Some data | here | and here |\n\
43/// | | | |\n\
44/// +---------------------+------+------------+\n\
45/// | Some data on a next | line | right here |\n\
46/// | | | |\n\
47/// +---------------------+------+------------+",
48/// )
49/// ```
50#[derive(Debug)]
51pub struct Height;
52
53impl Height {
54 /// Create [`CellHeightIncrease`] to set a table/cell height.
55 ///
56 /// # Example
57 ///
58 /// ## Cell height
59 ///
60 /// ```
61 /// use tabled::{Table, Height, Modify, object::Columns};
62 ///
63 /// let data = vec![
64 /// ("Some data", "here", "and here"),
65 /// ("Some data on a next", "line", "right here"),
66 /// ];
67 ///
68 /// let table = Table::new(data)
69 /// .with(Modify::new(Columns::first()).with(Height::increase(5)))
70 /// .to_string();
71 ///
72 /// assert_eq!(
73 /// table,
74 /// "+---------------------+------+------------+\n\
75 /// | &str | &str | &str |\n\
76 /// | | | |\n\
77 /// | | | |\n\
78 /// | | | |\n\
79 /// | | | |\n\
80 /// +---------------------+------+------------+\n\
81 /// | Some data | here | and here |\n\
82 /// | | | |\n\
83 /// | | | |\n\
84 /// | | | |\n\
85 /// | | | |\n\
86 /// +---------------------+------+------------+\n\
87 /// | Some data on a next | line | right here |\n\
88 /// | | | |\n\
89 /// | | | |\n\
90 /// | | | |\n\
91 /// | | | |\n\
92 /// +---------------------+------+------------+"
93 /// )
94 /// ```
95 ///
96 /// ## Table height
97 ///
98 /// ```
99 /// use tabled::{Table, Height};
100 ///
101 /// let data = vec![
102 /// ("Some data", "here", "and here"),
103 /// ("Some data on a next", "line", "right here"),
104 /// ];
105 ///
106 /// let table = Table::new(data)
107 /// .with(Height::increase(10))
108 /// .to_string();
109 ///
110 /// assert_eq!(
111 /// table,
112 /// "+---------------------+------+------------+\n\
113 /// | &str | &str | &str |\n\
114 /// | | | |\n\
115 /// +---------------------+------+------------+\n\
116 /// | Some data | here | and here |\n\
117 /// | | | |\n\
118 /// +---------------------+------+------------+\n\
119 /// | Some data on a next | line | right here |\n\
120 /// | | | |\n\
121 /// +---------------------+------+------------+",
122 /// )
123 /// ```
124 pub fn increase<W>(width: W) -> CellHeightIncrease<W>
125 where
126 W: Measurment<Height>,
127 {
128 CellHeightIncrease::new(width)
129 }
130
131 /// Create [`CellHeightLimit`] to set a table/cell height.
132 ///
133 /// # Example
134 ///
135 /// ## Cell height
136 ///
137 /// ```
138 /// use tabled::{Table, Height, Modify, object::Columns};
139 ///
140 /// let data = vec![
141 /// ("Some\ndata", "here", "and here"),
142 /// ("Some\ndata on a next", "line", "right here"),
143 /// ];
144 ///
145 /// let table = Table::new(data)
146 /// .with(Modify::new(Columns::first()).with(Height::limit(1)))
147 /// .to_string();
148 ///
149 /// assert_eq!(
150 /// table,
151 /// "+------+------+------------+\n\
152 /// | &str | &str | &str |\n\
153 /// +------+------+------------+\n\
154 /// | Some | here | and here |\n\
155 /// +------+------+------------+\n\
156 /// | Some | line | right here |\n\
157 /// +------+------+------------+"
158 /// )
159 /// ```
160 ///
161 /// ## Table height
162 ///
163 /// ```
164 /// use tabled::{Table, Height};
165 ///
166 /// let data = vec![
167 /// ("Some\ndata", "here", "and here"),
168 /// ("Some\ndata on a next", "line", "right here"),
169 /// ];
170 ///
171 /// let table = Table::new(&data)
172 /// .with(Height::limit(6))
173 /// .to_string();
174 ///
175 /// assert_eq!(
176 /// table,
177 /// "+----------------+------+------------+\n\
178 /// +----------------+------+------------+\n\
179 /// | Some | here | and here |\n\
180 /// +----------------+------+------------+\n\
181 /// | Some | line | right here |\n\
182 /// +----------------+------+------------+",
183 /// );
184 ///
185 /// let table = Table::new(&data)
186 /// .with(Height::limit(1))
187 /// .to_string();
188 ///
189 /// assert_eq!(
190 /// table,
191 /// "+----------------+------+------------+\n\
192 /// +----------------+------+------------+\n\
193 /// +----------------+------+------------+\n\
194 /// +----------------+------+------------+",
195 /// );
196 /// ```
197 pub fn limit<W>(width: W) -> CellHeightLimit<W>
198 where
199 W: Measurment<Height>,
200 {
201 CellHeightLimit::new(width)
202 }
203
204 /// Create [`HeightList`] to set a table height to a constant list of row heights.
205 ///
206 /// Notice if you provide a list with `.len()` less than `Table::count_rows` then it will have no affect.
207 ///
208 /// # Example
209 ///
210 /// ```
211 /// use tabled::{Table, Height, Modify, object::Columns};
212 ///
213 /// let data = vec![
214 /// ("Some\ndata", "here", "and here"),
215 /// ("Some\ndata on a next", "line", "right here"),
216 /// ];
217 ///
218 /// let table = Table::new(data)
219 /// .with(Height::list([1, 0, 2]))
220 /// .to_string();
221 ///
222 /// assert_eq!(
223 /// table,
224 /// "+----------------+------+------------+\n\
225 /// | &str | &str | &str |\n\
226 /// +----------------+------+------------+\n\
227 /// +----------------+------+------------+\n\
228 /// | Some | line | right here |\n\
229 /// | data on a next | | |\n\
230 /// +----------------+------+------------+",
231 /// )
232 /// ```
233 pub fn list<I>(rows: I) -> HeightList
234 where
235 I: IntoIterator<Item = usize>,
236 {
237 HeightList::new(rows.into_iter().collect())
238 }
239}
240
241pub(crate) fn get_table_total_height<R, E>(records: &R, cfg: &GridConfig, ctrl: &E) -> usize
242where
243 R: Records,
244 E: Estimate<R>,
245{
246 ctrl.total()
247 + cfg.count_horizontal(records.count_rows())
248 + cfg.get_margin().top.size
249 + cfg.get_margin().bottom.size
250}
251
252pub(crate) fn get_table_total_height2<R>(records: &R, cfg: &GridConfig) -> (usize, Vec<usize>)
253where
254 R: Records,
255{
256 let mut ctrl = HeightEstimator::default();
257 ctrl.estimate(records, cfg);
258 let total = <HeightEstimator as Estimate<R>>::total(&ctrl)
259 + cfg.count_horizontal(records.count_rows())
260 + cfg.get_margin().top.size
261 + cfg.get_margin().bottom.size;
262
263 (total, ctrl.into())
264}