-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcsv.rs
More file actions
65 lines (57 loc) · 1.86 KB
/
csv.rs
File metadata and controls
65 lines (57 loc) · 1.86 KB
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
use std::{collections::HashMap, fs};
use csv::Reader;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::opts::{CsvOpts, OutputFormat};
use anyhow::Ok;
const TOML_ROOT_KEY: &str = "data";
#[allow(dead_code)]
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Player {
name: String,
position: String,
#[serde(rename = "DOB")]
dob: String,
nationality: String,
#[serde(rename = "Kit Number")]
kit: u8,
}
pub fn process_csv(opts: &CsvOpts) -> anyhow::Result<()> {
let output = match &opts.output {
Some(output) => output.clone(),
None => format!("output.{}", opts.format),
};
println!(
"Processing CSV file: {}, output file: {}",
opts.input, output
);
let mut reader_builder = Reader::from_path(&opts.input)?;
let mut parsed_records = Vec::with_capacity(128);
let headers = reader_builder.headers()?.clone();
for result in reader_builder.records() {
let record = result?;
let json_value = serde_json::Value::Object(
headers
.iter()
// zip() the headers and record into a JSON object
.zip(record.iter())
.map(|(k, v)| (k.to_string(), Value::String(v.to_string())))
.collect(),
);
parsed_records.push(json_value);
}
let content = match opts.format {
OutputFormat::Json => serde_json::to_string_pretty(&parsed_records)?,
OutputFormat::Yaml => serde_yaml::to_string(&parsed_records)?,
// TOML format requires the root element
OutputFormat::Toml => {
let mut map = HashMap::new();
map.insert(TOML_ROOT_KEY, &parsed_records);
toml::to_string(&map)?
}
};
fs::write(output, content)?;
println!("File converted successfully.");
Ok(())
}