formats/
io_csv.rs

1use super::data_struct::{Row, Tabular};
2use super::error::IOError;
3use super::read_file;
4use csv::{ReaderBuilder, Trim};
5use std::error::Error;
6
7pub fn read_csv(path: &str) -> Result<Tabular, Box<Error>> {
8    let text = read_file(path)?;
9    parse_csv(&text)
10}
11
12pub fn parse_csv(text: &str) -> Result<Tabular, Box<Error>> {
13    let mut rdr = ReaderBuilder::new()
14        .trim(Trim::All)
15        .from_reader(text.as_bytes());
16    let header = Row::from_iter(rdr.headers()?.iter());
17    let mut data = Tabular::new(header);
18    let mut has_error = false;
19    // ignore error row
20    data.add_data_from_iter(
21        rdr.records()
22            .take_while(|row| match row {
23                Ok(_) => true,
24                Err(_) => {
25                    has_error = true;
26                    false
27                }
28            })
29            .map(|row| Row::from_iter(row.unwrap().iter())),
30    );
31    if has_error {
32        Err(Box::new(IOError::new("error reading csv")))
33    } else {
34        Ok(data)
35    }
36}