csvsc 0.1.0

Build processing chains for CSV files
Documentation
use crate::{Headers, Row, RowStream, RowResult};

pub struct MapRow<I, F> {
    iter: I,
    f: F,
    headers: Headers,
}

/// Allows you to build a custom transformation of the current row
impl<I, F> MapRow<I, F>
where
    I: RowStream,
    F: Fn(&Headers, &Row) -> RowResult,
{
    pub fn new(
        iter: I,
        f: F,
    ) -> MapRow<I, F> {
        let headers = iter.headers().clone();

        MapRow {
            iter,
            f,
            headers,
        }
    }
}

pub struct IntoIter<I, F> {
    iter: I,
    f: F,
    headers: Headers,
}

impl<I, F> Iterator for IntoIter<I, F>
where
    I: Iterator<Item = RowResult>,
    F: Fn(&Headers, &Row) -> RowResult,
{
    type Item = RowResult;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(|result| {
            result.and_then(|val| (self.f)(&self.headers, &val))
        })
    }
}

impl<I, F> IntoIterator for MapRow<I, F>
where
    I: RowStream,
    F: Fn(&Headers, &Row) -> RowResult,
{
    type Item = RowResult;

    type IntoIter = IntoIter<I::IntoIter, F>;

    fn into_iter(self) -> Self::IntoIter {
        Self::IntoIter {
            iter: self.iter.into_iter(),
            f: self.f,
            headers: self.headers,
        }
    }
}

impl<I, F> RowStream for MapRow<I, F>
where
    I: RowStream,
    F: Fn(&Headers, &Row) -> RowResult,
{
    fn headers(&self) -> &Headers {
        &self.headers
    }
}