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}