Fri, 18 Nov 2022 10:34:04 +0200
Add some keywords and categories
/*! Helper traits and functions for dumping data into CSV or JSON files. */ use std::slice::Iter; use csv; use serde_json; use serde::Serialize; use crate::error::DynError; /// Write a CSV from an iterator of [serde-serializable][Serialize] items. pub fn write_csv<I, J>(mut iter : I, filename : String) -> DynError where I : Iterator<Item=J>, J : Serialize { let wtr = csv::WriterBuilder::new() .has_headers(true) .delimiter(b'\t') .from_path(filename); 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 of [serde-serializable][Serialize] items. pub fn write_json<I, J>(iter : I, filename : String) -> DynError where I : Iterator<Item=J>, J : Serialize { let v : Vec<J> = iter.collect(); serde_json::to_writer_pretty(std::fs::File::create(filename)?, &v)?; Ok(()) } /// Trait that should be implemented by types that can be dumped into CSV (or JSON) files. /// /// The method that needs to be implemented is [`Self::tabledump_entries`] that prodvides an /// iterator over the items to be dumped. Moreover, the items themselves need to be /// [serde-serializable][`Serialize`]. Caveats about [`csv`] crate restrictions on writable /// data apply for CSV writing. pub trait TableDump<'a> where <Self::Iter as Iterator>::Item : Serialize { /// Iterator over the items to be dumped. type Iter : Iterator; // Return the headers of the CSV file. //fn tabledump_headers(&'a self) -> Vec<String>; /// Return an iterator over the rows that would be dumped into a 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() } }