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 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}