marko/
markdown_table.rs

1mod table;
2use table::Table;
3
4use std::collections::HashMap;
5
6pub fn create_markdown_table(headers: &[&str], rows: &[HashMap<&str, &str>]) -> Vec<String> {
7    if headers.is_empty() || rows.is_empty() {
8        return Vec::new();
9    }
10
11    let table = Table::from(headers, rows);
12
13    let value_pad_map = table.get_column_widths();
14
15    let padded_headers: Vec<_> = headers
16        .iter()
17        .map(|header| create_padded_value(header, value_pad_map[header]))
18        .collect();
19
20    let separators: Vec<_> = headers
21        .iter()
22        .map(|header| "-".repeat(value_pad_map[header]))
23        .collect();
24
25    let mut markdown_table = vec![
26        create_row_string(&padded_headers),
27        create_row_string(&separators),
28    ];
29
30    for row in rows {
31        let row_values: Vec<_> = headers
32            .iter()
33            .map(|header| create_padded_value(row[header], value_pad_map[header]))
34            .collect();
35
36        markdown_table.push(create_row_string(&row_values));
37    }
38
39    markdown_table
40}
41
42fn create_padded_value(value: &str, pad_value: usize) -> String {
43    format!("{:01$}", value, pad_value)
44}
45
46fn create_row_string(row: &[String]) -> String {
47    format!("| {} |", row.join(" | "))
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn table_empty_headers() {
56        let rows = [
57            HashMap::from([("Name", "Joseph"), ("Profession", "Developer")]),
58            HashMap::from([("Name", "Sam"), ("Profession", "Carpenter")]),
59        ];
60
61        let headers = [];
62
63        let table_lines = create_markdown_table(&headers, &rows);
64        let expected_output: Vec<String> = Vec::new();
65
66        assert_eq!(table_lines, expected_output)
67    }
68
69    #[test]
70    fn table_empty_rows() {
71        let rows = [];
72        let headers = ["Name", "Profession"];
73
74        let table_lines = create_markdown_table(&headers, &rows);
75        let expected_output: Vec<String> = Vec::new();
76
77        assert_eq!(table_lines, expected_output)
78    }
79
80    #[test]
81    fn table_with_values() {
82        let rows = [
83            HashMap::from([("Name", "Joseph"), ("Profession", "Developer")]),
84            HashMap::from([("Name", "Sam"), ("Profession", "Carpenter")]),
85        ];
86
87        let mut headers: Vec<_> = rows.first().unwrap().keys().cloned().collect();
88        headers.sort();
89
90        let table_lines = create_markdown_table(&headers, &rows);
91
92        let expected_output = [
93            "| Name   | Profession |".to_string(),
94            "| ------ | ---------- |".to_string(),
95            "| Joseph | Developer  |".to_string(),
96            "| Sam    | Carpenter  |".to_string(),
97        ];
98
99        assert_eq!(table_lines, expected_output);
100    }
101}