1use crate::generator::{TableBuilder, TableCell, TableRow};
6
7pub fn simple_table(rows: usize, cols: usize) -> TableBuilder {
16 let col_width = 9144000 / cols as u32; let column_widths = vec![col_width; cols];
18 let mut builder = TableBuilder::new(column_widths);
19
20 for _ in 0..rows {
22 let cells = (0..cols).map(|_| TableCell::new("")).collect();
23 builder = builder.add_row(TableRow::new(cells));
24 }
25
26 builder
27}
28
29pub fn table_with_widths(widths_inches: &[f64]) -> TableBuilder {
38 let column_widths: Vec<u32> = widths_inches
39 .iter()
40 .map(|w| (w * 914400.0) as u32)
41 .collect();
42 TableBuilder::new(column_widths)
43}
44
45pub fn table_from_data(data: &[Vec<&str>], column_widths: Option<Vec<f64>>) -> TableBuilder {
59 if data.is_empty() {
60 return simple_table(0, 0);
61 }
62
63 let cols = data[0].len();
64 let widths = if let Some(widths) = column_widths {
65 widths.iter().map(|w| (w * 914400.0) as u32).collect()
66 } else {
67 let col_width = 9144000 / cols as u32;
68 vec![col_width; cols]
69 };
70
71 let mut builder = TableBuilder::new(widths);
72
73 for row_data in data {
74 let cells: Vec<TableCell> = row_data.iter().map(|&text| TableCell::new(text)).collect();
75 builder = builder.add_row(TableRow::new(cells));
76 }
77
78 builder
79}
80
81pub fn table_with_header(headers: &[&str], data_rows: usize) -> TableBuilder {
91 let cols = headers.len();
92 let col_width = 9144000 / cols as u32;
93 let column_widths = vec![col_width; cols];
94
95 let mut builder = TableBuilder::new(column_widths);
96
97 let header_cells: Vec<TableCell> = headers
99 .iter()
100 .map(|&text| {
101 TableCell::new(text)
102 .bold()
103 .background_color("1F4E79")
104 .text_color("FFFFFF")
105 .align_center()
106 })
107 .collect();
108 builder = builder.add_row(TableRow::new(header_cells));
109
110 for _ in 0..data_rows {
112 let cells = (0..cols).map(|_| TableCell::new("")).collect();
113 builder = builder.add_row(TableRow::new(cells));
114 }
115
116 builder
117}
118
119pub struct QuickTable {
121 builder: TableBuilder,
122 #[allow(dead_code)]
123 cols: usize,
124}
125
126impl QuickTable {
127 pub fn new(cols: usize) -> Self {
129 let col_width = 9144000 / cols as u32;
130 let column_widths = vec![col_width; cols];
131 Self {
132 builder: TableBuilder::new(column_widths),
133 cols,
134 }
135 }
136
137 pub fn with_widths(widths_inches: &[f64]) -> Self {
139 let column_widths: Vec<u32> = widths_inches
140 .iter()
141 .map(|w| (w * 914400.0) as u32)
142 .collect();
143 Self {
144 builder: TableBuilder::new(column_widths.clone()),
145 cols: column_widths.len(),
146 }
147 }
148
149 pub fn header(mut self, headers: &[&str]) -> Self {
151 let cells: Vec<TableCell> = headers
152 .iter()
153 .map(|&text| {
154 TableCell::new(text)
155 .bold()
156 .background_color("1F4E79")
157 .text_color("FFFFFF")
158 .align_center()
159 })
160 .collect();
161 self.builder = self.builder.add_row(TableRow::new(cells));
162 self
163 }
164
165 pub fn row(mut self, data: &[&str]) -> Self {
167 let cells: Vec<TableCell> = data.iter().map(|&text| TableCell::new(text)).collect();
168 self.builder = self.builder.add_row(TableRow::new(cells));
169 self
170 }
171
172 pub fn styled_row(mut self, cells: Vec<TableCell>) -> Self {
174 self.builder = self.builder.add_row(TableRow::new(cells));
175 self
176 }
177
178 pub fn rows(mut self, data: &[Vec<&str>]) -> Self {
180 for row_data in data {
181 let cells: Vec<TableCell> = row_data.iter().map(|&text| TableCell::new(text)).collect();
182 self.builder = self.builder.add_row(TableRow::new(cells));
183 }
184 self
185 }
186
187 pub fn at(mut self, x: f64, y: f64) -> Self {
189 self.builder = self
190 .builder
191 .position((x * 914400.0) as u32, (y * 914400.0) as u32);
192 self
193 }
194
195 pub fn build(self) -> crate::generator::Table {
197 self.builder.build()
198 }
199}
200
201pub fn cell(text: &str) -> TableCell {
203 TableCell::new(text)
204}
205
206pub fn header_cell(text: &str) -> TableCell {
208 TableCell::new(text)
209 .bold()
210 .background_color("1F4E79")
211 .text_color("FFFFFF")
212 .align_center()
213}
214
215pub fn highlight_cell(text: &str, color: &str) -> TableCell {
217 TableCell::new(text).background_color(color).bold()
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223
224 #[test]
225 fn test_simple_table() {
226 let _table = simple_table(3, 4);
227 }
229
230 #[test]
231 fn test_table_with_widths() {
232 let _table = table_with_widths(&[2.0, 3.0, 2.5]);
233 }
235
236 #[test]
237 fn test_table_from_data() {
238 let data = vec![
239 vec!["Name", "Age", "City"],
240 vec!["Alice", "30", "NYC"],
241 vec!["Bob", "25", "LA"],
242 ];
243 let _table = table_from_data(&data, None);
244 }
246
247 #[test]
248 fn test_quick_table() {
249 let _table = QuickTable::new(3)
250 .header(&["Name", "Age", "City"])
251 .row(&["Alice", "30", "NYC"])
252 .row(&["Bob", "25", "LA"])
253 .at(0.5, 1.5)
254 .build();
255 }
257}