Read CSV to struct, add extra fields
examples/csv/csv-struct-extra-fields/Cargo.toml
[package] name = "handle-csv" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] csv = "1.2.2" serde = { version = "1.0", features = ["derive"] }
Record { name: "Mercury", distance: 0.4, mass: 0.055, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Venus", distance: 0.7, mass: 0.815, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Earth", distance: 1.0, mass: 1.0, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Mars", distance: 1.5, mass: 0.107, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Ceres", distance: 2.77, mass: 0.00015, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Jupiter", distance: 5.2, mass: 318.0, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Saturn", distance: 9.5, mass: 95.0, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Uranus", distance: 19.6, mass: 14.0, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Neptune", distance: 30.0, mass: 17.0, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Pluto", distance: 39.0, mass: 0.00218, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } Record { name: "Charon", distance: 39.0, mass: 0.000254, text: "abc", float: 0.0, person: Person { name: "", birth_year: 0 } } --- Mars 1.5 0.107 abc 0 0
examples/csv/csv-struct-extra-fields/planets.csv
Planet name,Distance (AU),Mass Mercury,0.4,0.055 Venus,0.7,0.815 Earth,1,1 Mars,1.5,0.107 Ceres,2.77,0.00015 Jupiter,5.2,318 Saturn,9.5,95 Uranus,19.6,14 Neptune,30,17 Pluto,39,0.00218 Charon,39,0.000254
examples/csv/csv-struct-extra-fields/src/main.rs
use std::error::Error; use std::fs::File; #[derive(Debug, serde::Deserialize)] struct Person { name: String, birth_year: u16, } #[derive(Debug, serde::Deserialize)] struct Record { #[serde(rename = "Planet name")] name: String, #[serde(rename = "Distance (AU)")] distance: f32, #[serde(rename = "Mass")] mass: f32, #[serde(default = "get_text")] text: String, #[serde(default = "get_zero")] float: f32, #[serde(default = "get_person")] person: Person, } fn get_text() -> String { String::from("abc") } fn get_zero() -> f32 { 0.0 } fn get_person() -> Person { Person { name: String::new(), birth_year: 0, } } fn main() { let filepath = "planets.csv"; let result = read_file(filepath); match result { Ok(rows) => { for row in &rows { println!("{:?}", row); } println!("---"); println!("{}", rows[3].name); println!("{}", rows[3].distance); println!("{}", rows[3].mass); println!("{}", rows[3].text); println!("{}", rows[3].float); println!("{}", rows[3].person.name); println!("{}", rows[3].person.birth_year); } Err(err) => panic!("Error: {}", err), } } fn read_file(filepath: &str) -> Result<Vec<Record>, Box<dyn Error>> { let mut records: Vec<Record> = vec![]; match File::open(filepath) { Ok(file) => { let mut rdr = csv::Reader::from_reader(file); for result in rdr.deserialize() { let record: Record = result?; records.push(record); } } Err(error) => panic!("Error opening file {}: {}", filepath, error), } Ok(records) }