Tue, 06 Dec 2022 08:29:13 +0200
cargo-d alias generation with a cargo-d script
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 |