Mon, 24 Oct 2022 09:41:43 +0300
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() } }