Tue, 25 Oct 2022 23:05:40 +0300
Added NormExponent trait for exponents of norms
| 5 | 1 | |
| 2 | /*! | |
| 3 | Helper traits and functions for dumping data into CSV or JSON files. | |
| 4 | */ | |
| 0 | 5 | |
| 6 | use std::slice::Iter; | |
| 7 | use csv; | |
| 8 | use serde_json; | |
| 9 | use serde::Serialize; | |
| 10 | use crate::error::DynError; | |
| 11 | ||
| 5 | 12 | /// Write a CSV from an iterator of [serde-serializable][Serialize] items. |
| 13 | pub fn write_csv<I, J>(mut iter : I, filename : String) -> DynError | |
| 0 | 14 | where I : Iterator<Item=J>, |
| 15 | J : Serialize { | |
| 16 | let wtr = csv::WriterBuilder::new() | |
| 17 | .has_headers(true) | |
| 18 | .delimiter(b'\t') | |
| 5 | 19 | .from_path(filename); |
| 0 | 20 | wtr.and_then(|mut w|{ |
| 21 | //w.write_record(self.tabledump_headers())?; | |
| 22 | iter.try_for_each(|item| w.serialize(item)) | |
| 23 | })?; | |
| 24 | Ok(()) | |
| 25 | } | |
| 26 | ||
| 5 | 27 | /// Write a JSON from an iterator of [serde-serializable][Serialize] items. |
| 28 | pub fn write_json<I, J>(iter : I, filename : String) -> DynError | |
| 0 | 29 | where I : Iterator<Item=J>, |
| 30 | J : Serialize { | |
| 31 | let v : Vec<J> = iter.collect(); | |
| 5 | 32 | serde_json::to_writer_pretty(std::fs::File::create(filename)?, &v)?; |
| 0 | 33 | Ok(()) |
| 34 | } | |
| 35 | ||
| 5 | 36 | /// Trait that should be implemented by types that can be dumped into CSV (or JSON) files. |
| 37 | /// | |
| 38 | /// The method that needs to be implemented is [`Self::tabledump_entries`] that prodvides an | |
| 39 | /// iterator over the items to be dumped. Moreover, the items themselves need to be | |
| 40 | /// [serde-serializable][`Serialize`]. Caveats about [`csv`] crate restrictions on writable | |
| 41 | /// data apply for CSV writing. | |
| 0 | 42 | pub trait TableDump<'a> |
| 43 | where <Self::Iter as Iterator>::Item : Serialize { | |
| 5 | 44 | /// Iterator over the items to be dumped. |
| 0 | 45 | type Iter : Iterator; |
| 46 | ||
| 47 | // Return the headers of the CSV file. | |
| 48 | //fn tabledump_headers(&'a self) -> Vec<String>; | |
| 49 | ||
| 5 | 50 | /// Return an iterator over the rows that would be dumped into a CSV file. |
| 0 | 51 | fn tabledump_entries(&'a self) -> Self::Iter; |
| 52 | ||
| 53 | /// Write a CSV file. | |
| 54 | fn write_csv(&'a self, f : String) -> DynError { | |
| 55 | write_csv(self.tabledump_entries(), f) | |
| 56 | } | |
| 57 | ||
| 58 | /// Write mapped CSV. This is a workaround to rust-csv not supporting struct flattening | |
| 59 | fn write_csv_mapped<D, G>(&'a self, f : String, g : G) -> DynError | |
| 60 | where D : Serialize, | |
| 61 | G : FnMut(<Self::Iter as Iterator>::Item) -> D { | |
| 62 | write_csv(self.tabledump_entries().map(g), f) | |
| 63 | } | |
| 64 | ||
| 65 | /// Write a JSON file. | |
| 66 | fn write_json(&'a self, f : String) -> DynError { | |
| 67 | write_json(self.tabledump_entries(), f) | |
| 68 | } | |
| 69 | } | |
| 70 | ||
| 71 | impl<'a, T : Serialize + 'a> TableDump<'a> for [T] { | |
| 72 | type Iter = Iter<'a, T>; | |
| 73 | ||
| 74 | // fn tabledump_headers(&'a self) -> Vec<String> { | |
| 75 | // vec!["value".into()] | |
| 76 | // } | |
| 77 | ||
| 78 | fn tabledump_entries(&'a self) -> Self::Iter { | |
| 79 | self.iter() | |
| 80 | } | |
| 81 | } | |
| 82 |