use std::collections::HashMap; use std::io::BufReader; use std::fs::File; use std::sync::Arc; use serde::Deserialize; #[derive(Debug)] pub struct Aircraft { pub owner: Option>, pub registration: Option, pub model: Option>, } #[derive(Debug, Deserialize)] struct Record { pub icao24: String, pub registration: String, pub manufacturername: String, pub model: String, pub owner: String, } pub struct Aircrafts { data: HashMap, } impl Aircrafts { pub fn load(file: &str) -> Self { let nullable = |s: String| { if s == "" { None } else { Some(s) } }; let mut stringtable = HashMap::new(); let mut stringtabled = |s: String| { let e = stringtable.entry(s.clone()) .or_insert_with(|| Arc::new(s)); e.clone() }; let mut data = HashMap::new(); let mut rdr = csv::Reader::from_reader(BufReader::new(File::open(file).unwrap())); for result in rdr.deserialize() { let rec: Record = result.unwrap(); if rec.registration != "" { data.insert(rec.icao24, Aircraft { owner: nullable(rec.owner).map(&mut stringtabled), registration: nullable(rec.registration), model: if rec.manufacturername == "" && rec.model == "" { None } else if rec.model.starts_with(&rec.manufacturername) { nullable(rec.model).map(&mut stringtabled) } else { Some(stringtabled(format!("{} {}", rec.manufacturername, rec.model))) }, }); } } println!("Loaded {} aircrafts ({} entries, {} strings)", data.len(), data.len(), stringtable.len()); Aircrafts { data, } } pub fn find<'s>(&'s self, hex: &str) -> Option<&'s Aircraft> { self.data.get(hex) } }