1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use build_html::{Html, Table};

pub fn convert(csv: &String, delimiter: &u8, has_header: &bool) -> String {
    let mut csv_reader = csv::ReaderBuilder::new()
        .delimiter(*delimiter)
        .from_reader(csv.as_bytes());
    let mut table = Table::new();
    match csv_reader.headers() {
        Ok(record) => {
            let header: Vec<&str> = record.iter().collect();
            if *has_header {
                table.add_header_row(header);
            } else {
                table.add_body_row(header);
            }
        }
        Err(_) => (),
    }
    let records = csv_reader.records();
    for r in records {
        match r {
            Ok(record) => table.add_body_row(record.iter().collect::<Vec<&str>>()),
            Err(_) => (),
        }
    }
    table.to_html_string()
}

#[cfg(test)]
mod tests {
    use super::*;

    fn compare(input: &str, output: &str, delimiter: &u8, has_header: &bool) {
        let input = std::fs::read_to_string(["data", input].join("/")).unwrap();
        let expected = std::fs::read_to_string(["data", output].join("/")).unwrap();
        assert!(convert(&input, delimiter, has_header) == expected);
    }

    #[test]
    fn random_100_100_header() {
        compare("random-100x100.csv", "random-100x100.html", &b',', &true);
    }

    #[test]
    fn random_100_100_no_header() {
        compare(
            "random-100x100.csv",
            "random-100x100-no-header.html",
            &b',',
            &false,
        );
    }

    #[test]
    fn space_delimiter() {
        compare("space.csv", "space.html", &b' ', &true);
    }
}