146 lines
3.5 KiB
Rust
146 lines
3.5 KiB
Rust
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<String>,
|
|
exact: bool,
|
|
) -> Result<HashMap<String, (f64, Option<System>)>, String> {
|
|
let mut best: HashMap<String, (f64, Option<System>)> = 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::<SystemSerde>();
|
|
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<System> {
|
|
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<Ordering> {
|
|
Some(self.cmp(other))
|
|
}
|
|
}
|