1use crate::TableOptions;
5use std::ops::Div;
6
7const THIN_HR_LINE_CHAR: &'static str = "-";
8const THICK_HR_LINE_CHAR: &'static str = "=";
9const THIN_VR_LINE_CHAR: &'static str = "|";
10
11pub fn generate_table_string_vec<S>(rows: Vec<Vec<S>>, options: Option<TableOptions>) -> Vec<String>
14where
15 S: Into<String>,
16{
17 let mut table_string_vec: Vec<String> = Vec::new();
18 let _options = options.unwrap_or_default();
19 let mut size_arr: Vec<usize> = vec![0; rows[0].len()];
20
21 let rows = rows
22 .into_iter()
23 .map(|row| {
24 row.into_iter()
25 .enumerate()
26 .map(|(cell_no, cell)| {
27 let cell_string: String = cell.into();
28
29 if (cell_string.len() + 2) > size_arr[cell_no] {
30 size_arr[cell_no] = cell_string.len() + 2;
31 }
32
33 cell_string
34 })
35 .collect::<Vec<String>>()
36 })
37 .collect::<Vec<Vec<String>>>();
38
39 enum HrLineType {
40 Header,
41 Cell,
42 }
43
44 let draw_hr_line = |line_type: HrLineType| -> String {
45 let mut line_string = String::from("+");
46
47 for size in size_arr.iter() {
48 match line_type {
49 HrLineType::Header => line_string.push_str(&THICK_HR_LINE_CHAR.repeat(*size)),
50 HrLineType::Cell => line_string.push_str(&THIN_HR_LINE_CHAR.repeat(*size)),
51 }
52
53 line_string.push('+');
54 }
55
56 line_string
57 };
58
59 let compute_spaces = |string_size: usize, reserved_size: usize| -> (usize, usize) {
60 let partitioned_space = (reserved_size - string_size).div(2);
61
62 match (reserved_size - string_size) % 2 == 0 {
63 true => (partitioned_space, partitioned_space),
64 false => (partitioned_space, partitioned_space + 1),
65 }
66 };
67
68 table_string_vec.push(draw_hr_line(HrLineType::Header));
69 table_string_vec.push({
70 let mut header_row: String = String::from(THIN_VR_LINE_CHAR.to_string());
72
73 for i in 0..rows[0].len() {
74 let spaces = compute_spaces(rows[0][i].len(), size_arr[i]);
75 header_row.push_str(&format!(
76 "{}{}{}{THIN_VR_LINE_CHAR}",
77 " ".repeat(spaces.0),
78 rows[0][i],
79 " ".repeat(spaces.1)
80 ));
81 }
82
83 header_row
84 });
85 table_string_vec.push(draw_hr_line(HrLineType::Header));
86
87 for row_no in 1..rows.len() {
89 let mut row_string: String = String::from(THIN_VR_LINE_CHAR.to_string());
90 for col_no in 0..rows[row_no].len() {
91 let spaces = compute_spaces(rows[row_no][col_no].len(), size_arr[col_no]);
92 row_string.push_str(&format!(
93 "{}{}{}{THIN_VR_LINE_CHAR}",
94 " ".repeat(spaces.0),
95 rows[row_no][col_no],
96 " ".repeat(spaces.1)
97 ));
98 }
99 table_string_vec.push(row_string);
100 table_string_vec.push(draw_hr_line(HrLineType::Cell));
101 }
102
103 table_string_vec
104}