1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::{input_file_name, Data, DataRow};
use csv::StringRecord;
use std::fs::File;
use tera::{Map, Value};
pub fn process_scsv_input<D, F>(
data: D,
file_name: &str,
process_row: F,
) -> Result<D, Box<dyn std::error::Error>>
where
D: Data,
F: Fn(StringRecord, &mut DataRow) -> Result<String, Box<dyn std::error::Error>>,
{
process_vsv_input(data, file_name, b';', process_row)
}
pub fn process_csv_input<D, F>(
data: D,
file_name: &str,
process_row: F,
) -> Result<D, Box<dyn std::error::Error>>
where
D: Data,
F: Fn(StringRecord, &mut DataRow) -> Result<String, Box<dyn std::error::Error>>,
{
process_vsv_input(data, file_name, b',', process_row)
}
pub fn process_tsv_input<D, F>(
data: D,
file_name: &str,
process_row: F,
) -> Result<D, Box<dyn std::error::Error>>
where
D: Data,
F: Fn(StringRecord, &mut DataRow) -> Result<String, Box<dyn std::error::Error>>,
{
process_vsv_input(data, file_name, b'\t', process_row)
}
pub fn process_vsv_input<D, F>(
mut data: D,
file_name: &str,
delimiter: u8,
process_row: F,
) -> Result<D, Box<dyn std::error::Error>>
where
D: Data,
F: Fn(StringRecord, &mut DataRow) -> Result<String, Box<dyn std::error::Error>>,
{
let file_name = input_file_name(file_name);
let mut rdr = csv::ReaderBuilder::new()
.has_headers(true)
.delimiter(delimiter)
.comment(Some(b'#'))
.trim(csv::Trim::All)
.from_reader(File::open(file_name)?);
for result in rdr.records() {
let record = result?;
let mut row: Map<String, Value> = Default::default();
let id = process_row(record, &mut row)?;
data.insert_row(&id, row);
}
Ok(data)
}