Mon, 24 Oct 2022 09:41:43 +0300
Allow step closure of AlgIterators to indicate succesfull termination or failure.
0 | 1 | |
2 | use std::slice::Iter; | |
3 | use csv; | |
4 | use serde_json; | |
5 | use serde::Serialize; | |
6 | use crate::error::DynError; | |
7 | ||
8 | /// Write a CSV from an iterator | |
9 | pub fn write_csv<I, J>(mut iter : I, f : String) -> DynError | |
10 | where I : Iterator<Item=J>, | |
11 | J : Serialize { | |
12 | let wtr = csv::WriterBuilder::new() | |
13 | .has_headers(true) | |
14 | .delimiter(b'\t') | |
15 | .from_path(f); | |
16 | wtr.and_then(|mut w|{ | |
17 | //w.write_record(self.tabledump_headers())?; | |
18 | iter.try_for_each(|item| w.serialize(item)) | |
19 | })?; | |
20 | Ok(()) | |
21 | } | |
22 | ||
23 | /// Write a JSON from an iterator | |
24 | pub fn write_json<I, J>(iter : I, f : String) -> DynError | |
25 | where I : Iterator<Item=J>, | |
26 | J : Serialize { | |
27 | let v : Vec<J> = iter.collect(); | |
28 | serde_json::to_writer_pretty(std::fs::File::create(f)?, &v)?; | |
29 | Ok(()) | |
30 | } | |
31 | ||
32 | /// Helper trait for dumping data in a CSV or JSON file. | |
33 | pub trait TableDump<'a> | |
34 | where <Self::Iter as Iterator>::Item : Serialize { | |
35 | /// Iterator over the rows | |
36 | type Iter : Iterator; | |
37 | ||
38 | // Return the headers of the CSV file. | |
39 | //fn tabledump_headers(&'a self) -> Vec<String>; | |
40 | ||
41 | /// Return an iterator over the rows of the CSV file. | |
42 | fn tabledump_entries(&'a self) -> Self::Iter; | |
43 | ||
44 | /// Write a CSV file. | |
45 | fn write_csv(&'a self, f : String) -> DynError { | |
46 | write_csv(self.tabledump_entries(), f) | |
47 | } | |
48 | ||
49 | /// Write mapped CSV. This is a workaround to rust-csv not supporting struct flattening | |
50 | fn write_csv_mapped<D, G>(&'a self, f : String, g : G) -> DynError | |
51 | where D : Serialize, | |
52 | G : FnMut(<Self::Iter as Iterator>::Item) -> D { | |
53 | write_csv(self.tabledump_entries().map(g), f) | |
54 | } | |
55 | ||
56 | /// Write a JSON file. | |
57 | fn write_json(&'a self, f : String) -> DynError { | |
58 | write_json(self.tabledump_entries(), f) | |
59 | } | |
60 | } | |
61 | ||
62 | impl<'a, T : Serialize + 'a> TableDump<'a> for [T] { | |
63 | type Iter = Iter<'a, T>; | |
64 | ||
65 | // fn tabledump_headers(&'a self) -> Vec<String> { | |
66 | // vec!["value".into()] | |
67 | // } | |
68 | ||
69 | fn tabledump_entries(&'a self) -> Self::Iter { | |
70 | self.iter() | |
71 | } | |
72 | } | |
73 |