serdeio 0.6.0

Tiny IO utility library for Rust to serialize/deserialize Serde compatible structs
Documentation
use std::io::{BufReader, BufWriter, Read, Write};

use serde::{Serialize, de::DeserializeOwned};

use crate::Error;

pub fn read<T: DeserializeOwned>(reader: impl Read) -> Result<Vec<T>, Error> {
    let mut rdr = csv::Reader::from_reader(BufReader::new(reader));
    let mut records: Vec<T> = Vec::new();
    for result in rdr.deserialize() {
        let record: T = result?;
        records.push(record);
    }
    Ok(records)
}

pub fn write<'a, T: Serialize + 'a>(
    writer: impl Write,
    records: impl IntoIterator<Item = &'a T>,
) -> Result<(), Error> {
    let mut wtr = csv::Writer::from_writer(BufWriter::new(writer));
    for record in records {
        wtr.serialize(record)?;
    }
    wtr.flush()?;
    Ok(())
}

#[cfg(test)]
mod test {
    use std::io::Cursor;

    use serde::{Deserialize, Serialize};

    use super::{read, write};

    #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
    struct Record {
        id: u32,
        name: String,
    }

    #[test]
    fn test_read() {
        let text = r#"
id,name
1,foo
2,bar"#;

        let records: Vec<Record> = read(Cursor::new(text)).unwrap();
        let expected = vec![
            Record {
                id: 1,
                name: "foo".to_owned(),
            },
            Record {
                id: 2,
                name: "bar".to_owned(),
            },
        ];
        assert_eq!(expected, records);
    }

    #[test]
    fn test_write() {
        let records = vec![
            Record {
                id: 1,
                name: "foo".to_owned(),
            },
            Record {
                id: 2,
                name: "bar".to_owned(),
            },
        ];
        let mut cursor = Cursor::new(vec![]);
        write(&mut cursor, &records).unwrap();
        let data = String::from_utf8(cursor.into_inner())
            .unwrap()
            .trim()
            .to_string();
        let expected = r#"
id,name
1,foo
2,bar"#
            .trim()
            .to_owned();
        assert_eq!(expected, data);
    }
}