easy_csv/
lib.rs

1#[macro_use]
2#[allow(unused_imports)]
3extern crate easy_csv_derive;
4extern crate csv;
5
6#[derive(Debug)]
7pub enum Error {
8    CSVError(csv::Error),
9    MissingColumnError(String),
10    ParseError(String)
11}
12
13impl std::convert::From<csv::Error> for Error {
14    fn from(e: csv::Error) -> Error {
15        Error::CSVError(e)
16    }
17}
18
19pub trait CSVParsable<T> {
20    fn parse_header<R: std::io::Read>(
21        reader: &mut csv::Reader<R>) -> Result<Vec<usize>, ::Error>;
22    fn parse_row<R: std::io::Read>(
23        reader: &mut std::iter::Enumerate<csv::StringRecords<R>>,
24        col_indices: &Vec<usize>) -> Option<Result<T, ::Error>>;
25}
26
27pub struct CSVIterator<'a, T, R> where T: CSVParsable<T>, R: 'a, R: std::io::Read {
28    records: std::iter::Enumerate<csv::StringRecords<'a, R>>,
29    col_indices: Vec<usize>,
30    _marker: std::marker::PhantomData<T>
31}
32
33impl<'a, T, R> CSVIterator<'a, T, R> where T: CSVParsable<T>, R: 'a, R: std::io::Read {
34    pub fn new(mut reader: &'a mut csv::Reader<R>) -> Result<Self, ::Error> {
35        let col_indices = try!(T::parse_header(&mut reader));
36        Ok(CSVIterator {
37            records: reader.records::<'a>().into_iter().enumerate(),
38            col_indices: col_indices,
39            _marker: std::marker::PhantomData::<T> {}
40        })
41    }
42}
43
44impl<'a, T, R> Iterator for CSVIterator<'a, T, R> where T: CSVParsable<T>, R: std::io::Read {
45    type Item=Result<T, ::Error>;
46
47    fn next(&mut self) -> Option<Self::Item> {
48        T::parse_row(&mut self.records, &self.col_indices)
49    }
50}