diff options
Diffstat (limited to 'src/parsers/csv/mod.rs')
| -rw-r--r-- | src/parsers/csv/mod.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/parsers/csv/mod.rs b/src/parsers/csv/mod.rs new file mode 100644 index 0000000..c906202 --- /dev/null +++ b/src/parsers/csv/mod.rs @@ -0,0 +1,93 @@ +use std::fs::File; +use std::io; +use std::io::BufRead; +use std::collections::HashMap; + +/** + Represents a CSV file + **/ + +pub struct CsvFile { + path : String, + delim : String, + pub header : Vec<String>, + pub content : Vec<Vec<String>>, + has_header : bool +} + +/* + * Iterator for the CSV file + */ +pub struct CsvFileIterator<'a> { + file : &'a CsvFile, + line : usize, + column : usize, + max_column : usize +} + +impl <'a> Iterator for CsvFileIterator<'a> { + type Item = HashMap<&'a String,&'a String>; + + fn next(&mut self) -> Option<Self::Item> { + let k = self.file.content.get(self.line)?; + let it : HashMap<&'a String, &'a String> = self.file.header.iter().zip(k.iter()).collect(); + self.line = self.line + 1; + Some(it) + } +} + +impl CsvFile { + pub fn new(path: &str, delim: &str, header: bool) -> CsvFile { + CsvFile { + path : String::from(path), + delim: String::from(delim), + header : Vec::new(), + content : Vec::new(), + has_header : header + } + + } + + // TODO nicht gleich viele spalten + fn parse_line(line : String, delim: &str) -> Vec<String> { + let mut columns : Vec<String> = Vec::new(); + for column in line.split(delim).collect::<Vec<&str>>() { + columns.push(column.trim_matches(|c| c == '\'' || c == '\"').to_string()); + } + columns + } + + + pub fn from_file(path: &str, delim: &str, header: bool) -> Result<CsvFile, io::Error> { + let fd = File::open(path)?; + let reader = io::BufReader::new(fd); + let mut column_names : Vec<String> = Vec::new(); + let mut lines : Vec<Vec<String>> = Vec::new(); + let mut first = true; + + for line in reader.lines() { + let line = line?; + if header && first { + column_names.append(&mut CsvFile::parse_line(line, delim)); + first = false; + } else { + lines.push(CsvFile::parse_line(line, delim)); + } + } + + Ok(CsvFile { path: String::from(path), + delim : String::from(delim), + header : column_names, + content : lines, + has_header: header } ) + } + + pub fn iter(&self) -> CsvFileIterator { + CsvFileIterator { file : self, + line : 0, + column : 0, + max_column : self.header.len() + } + } + +} |
