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 mut strings = HashMap::new(); let mut nullable = move |s: String| { if s.len() > 0 { let e = strings.entry(s.clone()) .or_insert_with(|| Arc::new(s)); Some(e.clone()) } else { None } }; 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), registration: nullable(rec.registration), model: if rec.manufacturername == "" && rec.model == "" { None } else if rec.model.starts_with(&rec.manufacturername) { nullable(rec.model) } else { nullable(format!("{} {}", rec.manufacturername, rec.model)) }, }); } } println!("Loaded aircraft database with {} entries", data.len()); Aircrafts { data, } } pub fn find<'s>(&'s self, hex: &str) -> Option<&'s Aircraft> { self.data.get(hex) } }