use std::sync::Arc; use geoffrey_db::helper::load_location; use geoffrey_models::models::locations::{Location, LocationDb}; use geoffrey_models::models::parameters::find_params::FindParams; use geoffrey_models::models::player::Player; use geoffrey_models::models::response::api_error::GeoffreyAPIError; use geoffrey_models::models::CommandLevel; use crate::api_endpoint::{ApiEndpoint, RequestType}; use crate::commands::Command; use crate::context::Context; use crate::Result; pub struct FindCommand {} impl ApiEndpoint for FindCommand { fn endpoint_name() -> String { "find".to_string() } fn request_type() -> RequestType { RequestType::GET } } impl Command for FindCommand { type Req = FindParams; type Resp = Vec; fn command_level() -> CommandLevel { CommandLevel::ALL } fn run_command(ctx: Arc, req: &Self::Req, _: Option) -> Result { let query = req.query.to_lowercase(); let players: Vec = ctx .db .filter(|_, player: &Player| { let player_name = player.name.to_lowercase(); player_name.contains(&query) })? .map(|player| player.id.unwrap()) .collect(); let locations: Vec = ctx .db .filter(|_, loc: &LocationDb| { let name = loc.name.to_lowercase(); name.contains(&query) || loc .owners() .iter() .any(|owner_id| players.contains(owner_id)) }) .map_err(GeoffreyAPIError::from)? .collect(); let locations: Result> = locations .iter() .map(|loc| load_location(&ctx.db, loc).map_err(GeoffreyAPIError::from)) .collect(); locations } }