src/tabledump.rs

Mon, 24 Oct 2022 09:41:43 +0300

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 24 Oct 2022 09:41:43 +0300
changeset 3
20db884b7028
parent 0
9f27689eb130
child 5
59dc4c5883f4
permissions
-rw-r--r--

Allow step closure of AlgIterators to indicate succesfull termination or failure.


use std::slice::Iter;
use csv;
use serde_json;
use serde::Serialize;
use crate::error::DynError;

/// Write a CSV from an iterator
pub fn write_csv<I, J>(mut iter : I, f : String) -> DynError
where I : Iterator<Item=J>,
      J : Serialize {
    let wtr = csv::WriterBuilder::new()
        .has_headers(true)
        .delimiter(b'\t')
        .from_path(f);
    wtr.and_then(|mut w|{
        //w.write_record(self.tabledump_headers())?;
        iter.try_for_each(|item| w.serialize(item))
    })?;
    Ok(())
}

/// Write a JSON from an iterator
pub fn write_json<I, J>(iter : I, f : String) -> DynError
where I : Iterator<Item=J>,
      J : Serialize {
    let v : Vec<J> = iter.collect();
    serde_json::to_writer_pretty(std::fs::File::create(f)?, &v)?;
    Ok(())
}

/// Helper trait for dumping data in a CSV or JSON file.
pub trait TableDump<'a>
where <Self::Iter as Iterator>::Item : Serialize {
    /// Iterator over the rows
    type Iter : Iterator;

    // Return the headers of the CSV file.
    //fn tabledump_headers(&'a self) -> Vec<String>;

    /// Return an iterator over the rows of the CSV file.
    fn tabledump_entries(&'a self) -> Self::Iter;

    /// Write a CSV file.
    fn write_csv(&'a self, f : String) -> DynError {
        write_csv(self.tabledump_entries(), f)
    }

    /// Write mapped CSV. This is a workaround to rust-csv not supporting struct flattening
    fn write_csv_mapped<D, G>(&'a self, f : String, g : G) -> DynError
    where D : Serialize,
          G : FnMut(<Self::Iter as Iterator>::Item) -> D {
        write_csv(self.tabledump_entries().map(g), f)
    }

    /// Write a JSON file.
    fn write_json(&'a self, f : String) -> DynError {
        write_json(self.tabledump_entries(), f)
    }
}

impl<'a, T : Serialize + 'a> TableDump<'a> for [T] {
    type Iter = Iter<'a, T>;

    // fn tabledump_headers(&'a self) -> Vec<String> {
    //     vec!["value".into()]
    // }

    fn tabledump_entries(&'a self) -> Self::Iter {
        self.iter()
    }
}

mercurial