use crate::route::Router; use dict_derive::IntoPyObject; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::collections::HashMap; use std::num::ParseIntError; use std::path::PathBuf; use std::str::FromStr; pub enum SysEntry { ID(u32), Name(String) } impl SysEntry { pub fn parse(s: &str) -> Self { if let Ok(n) = s.parse() { SysEntry::ID(n) } else { SysEntry::Name(s.to_owned()) } } } pub fn find_matches( path: &PathBuf, names: Vec, exact: bool, ) -> Result)>, String> { let mut best: HashMap)> = HashMap::new(); if names.is_empty() { return Ok(best); } for name in &names { best.insert(name.to_string(), (0.0, None)); } let mut reader = match csv::ReaderBuilder::new().from_path(path) { Ok(rdr) => rdr, Err(e) => { return Err(format!("Error opening {}: {}", path.to_str().unwrap(), e).to_string()); } }; let systems = reader.deserialize::(); for sys in systems { let sys = sys.unwrap(); for name in &names { best.entry(name.clone()).and_modify(|ent| { if (exact) && (&sys.system == name) { *ent = (1.0, Some(sys.clone().build())) } else { let d1 = strsim::normalized_levenshtein(&sys.system, &name); let d2 = strsim::normalized_levenshtein(&sys.body, &name); if d1 > ent.0 { *ent = (d1, Some(sys.clone().build())) } else if d2 > ent.0 { *ent = (d2, Some(sys.clone().build())) } } }); } } Ok(best) } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct TreeNode { pub id: u32, pub pos: [f32; 3], pub mult: f32, } impl TreeNode { pub fn get(&self, router: &Router) -> Option { let mut cache = router.cache.as_ref().unwrap().lock().unwrap(); cache.get(self.id) } } #[derive(Debug, Clone, Serialize, Deserialize, IntoPyObject)] pub struct SystemSerde { pub id: u32, pub star_type: String, pub system: String, pub body: String, pub mult: f32, pub distance: u32, pub x: f32, pub y: f32, pub z: f32, } impl SystemSerde { pub fn build(self) -> System { System { id: self.id, star_type: self.star_type, system: self.system, body: self.body, mult: self.mult, distance: self.distance, pos: [self.x, self.y, self.z], } } pub fn to_node(&self) -> TreeNode { TreeNode { id: self.id, pos: [self.x, self.y, self.z], mult: self.mult, } } } #[derive(Debug, Clone, Deserialize, Serialize)] pub struct System { pub id: u32, pub star_type: String, pub system: String, pub body: String, pub mult: f32, pub distance: u32, pub pos: [f32; 3], } impl System { pub fn to_node(&self) -> TreeNode { TreeNode { id: self.id, pos: self.pos, mult: self.mult, } } } impl Ord for System { fn cmp(&self, other: &Self) -> Ordering { self.id.cmp(&other.id) } } impl PartialOrd for System { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } }