use crate::commands::{Command, RequestType}; use crate::context::Context; use crate::Result; use geoffrey_db::helper::load_location; use geoffrey_db::query::QueryBuilder; use geoffrey_models::models::locations::{Location, LocationDb}; use geoffrey_models::models::parameters::info_params::InfoParams; use geoffrey_models::models::player::Player; use geoffrey_models::models::response::api_error::GeoffreyAPIError; use geoffrey_models::models::CommandLevel; use std::sync::Arc; use strsim::normalized_damerau_levenshtein; pub struct InfoCommand {} impl Command for InfoCommand { type Req = InfoParams; type Resp = Location; fn command_name() -> String { "info".to_string() } fn request_type() -> RequestType { RequestType::GET } fn command_level() -> CommandLevel { CommandLevel::ALL } fn run_command(ctx: Arc, req: &Self::Req, _: Option) -> Result { let query = QueryBuilder::::default() .with_name_regex_case_insensitive(&req.location_name)?; let mut locations = ctx.db.run_query(query)?; if locations.is_empty() { Err(GeoffreyAPIError::EntryNotFound) } else { locations.sort_by(|a, b| { let a = (normalized_damerau_levenshtein(&a.name, &req.location_name) * 1000.0) as u32; let b = (normalized_damerau_levenshtein(&b.name, &req.location_name) * 1000.0) as u32; a.cmp(&b) }); Ok(load_location(&ctx.db, &locations.pop().unwrap())?) } } }