/rust/registry/src/index.crates.io-1949cf8c6b5b557f/papergrid-0.18.0/src/dimension/compact.rs
Line | Count | Source |
1 | | //! The module contains a [`CompactGridDimension`] for [`CompactGrid`] height/width estimation. |
2 | | //! |
3 | | //! [`CompactGrid`]: crate::grid::compact::CompactGrid |
4 | | |
5 | | use core::cmp::max; |
6 | | |
7 | | use crate::{ |
8 | | config::compact::CompactConfig, |
9 | | dimension::{Dimension, Estimate}, |
10 | | records::{IntoRecords, Records}, |
11 | | util::string::{count_lines, get_text_width}, |
12 | | }; |
13 | | |
14 | | /// A [`Dimension`] implementation which calculates exact column/row width/height. |
15 | | /// |
16 | | /// [`Grid`]: crate::grid::iterable::Grid |
17 | | #[derive(Debug, Default, Clone, PartialEq, Eq)] |
18 | | pub struct CompactGridDimension { |
19 | | width: Vec<usize>, |
20 | | } |
21 | | |
22 | | impl CompactGridDimension { |
23 | | /// Calculates height of rows. |
24 | 0 | pub fn height<R>(records: R, cfg: &CompactConfig) -> Vec<usize> |
25 | 0 | where |
26 | 0 | R: Records, |
27 | 0 | <R::Iter as IntoRecords>::Cell: AsRef<str>, |
28 | | { |
29 | 0 | build_height(records, cfg) |
30 | 0 | } |
31 | | |
32 | | /// Calculates width of columns. |
33 | 0 | pub fn width<R>(records: R, cfg: &CompactConfig) -> Vec<usize> |
34 | 0 | where |
35 | 0 | R: Records, |
36 | 0 | <R::Iter as IntoRecords>::Cell: AsRef<str>, |
37 | | { |
38 | 0 | build_width(records, cfg) |
39 | 0 | } |
40 | | |
41 | | /// Calculates dimensions of columns. |
42 | 0 | pub fn dimension<R>(records: R, cfg: &CompactConfig) -> (Vec<usize>, Vec<usize>) |
43 | 0 | where |
44 | 0 | R: Records, |
45 | 0 | <R::Iter as IntoRecords>::Cell: AsRef<str>, |
46 | | { |
47 | 0 | build_dimension(records, cfg) |
48 | 0 | } |
49 | | } |
50 | | |
51 | | impl Dimension for CompactGridDimension { |
52 | 0 | fn get_width(&self, column: usize) -> usize { |
53 | 0 | self.width[column] |
54 | 0 | } |
55 | | |
56 | 0 | fn get_height(&self, _: usize) -> usize { |
57 | 0 | 1 |
58 | 0 | } |
59 | | } |
60 | | |
61 | | impl<R> Estimate<R, CompactConfig> for CompactGridDimension |
62 | | where |
63 | | R: Records, |
64 | | <R::Iter as IntoRecords>::Cell: AsRef<str>, |
65 | | { |
66 | 0 | fn estimate(&mut self, records: R, cfg: &CompactConfig) { |
67 | 0 | self.width = build_width(records, cfg); |
68 | 0 | } |
69 | | } |
70 | | |
71 | 0 | fn build_dimension<R>(records: R, cfg: &CompactConfig) -> (Vec<usize>, Vec<usize>) |
72 | 0 | where |
73 | 0 | R: Records, |
74 | 0 | <R::Iter as IntoRecords>::Cell: AsRef<str>, |
75 | | { |
76 | 0 | let mut heights = vec![]; |
77 | 0 | let mut widths = vec![0; records.count_columns()]; |
78 | | |
79 | 0 | for columns in records.iter_rows() { |
80 | 0 | let mut row_height = 0; |
81 | 0 | for (col, cell) in columns.into_iter().enumerate() { |
82 | 0 | let height = get_cell_height(cell.as_ref(), cfg); |
83 | 0 | let width = get_cell_width(cell.as_ref(), cfg); |
84 | 0 | row_height = max(row_height, height); |
85 | 0 | widths[col] = max(widths[col], width) |
86 | | } |
87 | | |
88 | 0 | heights.push(row_height); |
89 | | } |
90 | | |
91 | 0 | (widths, heights) |
92 | 0 | } |
93 | | |
94 | 0 | fn build_height<R>(records: R, cfg: &CompactConfig) -> Vec<usize> |
95 | 0 | where |
96 | 0 | R: Records, |
97 | 0 | <R::Iter as IntoRecords>::Cell: AsRef<str>, |
98 | | { |
99 | 0 | let mut heights = vec![]; |
100 | | |
101 | 0 | for columns in records.iter_rows() { |
102 | 0 | let mut row_height = 0; |
103 | 0 | for cell in columns.into_iter() { |
104 | 0 | let height = get_cell_height(cell.as_ref(), cfg); |
105 | 0 | row_height = max(row_height, height); |
106 | 0 | } |
107 | | |
108 | 0 | heights.push(row_height); |
109 | | } |
110 | | |
111 | 0 | heights |
112 | 0 | } |
113 | | |
114 | 0 | fn build_width<R>(records: R, cfg: &CompactConfig) -> Vec<usize> |
115 | 0 | where |
116 | 0 | R: Records, |
117 | 0 | <R::Iter as IntoRecords>::Cell: AsRef<str>, |
118 | | { |
119 | 0 | let mut widths = vec![0; records.count_columns()]; |
120 | 0 | for columns in records.iter_rows() { |
121 | 0 | for (col, cell) in columns.into_iter().enumerate() { |
122 | 0 | let width = get_cell_width(cell.as_ref(), cfg); |
123 | 0 | widths[col] = max(widths[col], width); |
124 | 0 | } |
125 | | } |
126 | | |
127 | 0 | widths |
128 | 0 | } |
129 | | |
130 | 0 | fn get_cell_height(cell: &str, cfg: &CompactConfig) -> usize { |
131 | 0 | let count_lines = max(1, count_lines(cell)); |
132 | 0 | let pad = cfg.get_padding(); |
133 | | |
134 | 0 | count_lines + pad.top.size + pad.bottom.size |
135 | 0 | } |
136 | | |
137 | 0 | fn get_cell_width(text: &str, cfg: &CompactConfig) -> usize { |
138 | 0 | let width = get_text_width(text); |
139 | 0 | let pad = cfg.get_padding(); |
140 | | |
141 | 0 | width + pad.left.size + pad.right.size |
142 | 0 | } |