use std::collections::HashSet; use std::sync::Arc; use geoffrey_db::helper::load_location; use geoffrey_db::query::QueryBuilder; use geoffrey_models::models::item::ItemListing; use geoffrey_models::models::locations::{Location, LocationDataDb, LocationDb, LocationType}; use geoffrey_models::models::parameters::item_command_params::ItemCommandParams; 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 Restock {} impl ApiEndpoint for Restock { fn endpoint_name() -> String { "restock".to_string() } fn request_type() -> RequestType { RequestType::POST } } impl Command for Restock { type Req = ItemCommandParams; type Resp = Location; fn command_level() -> CommandLevel { CommandLevel::REGISTERED } fn run_command(ctx: Arc, req: &Self::Req, user: Option) -> Result { let user = user.unwrap(); let query = QueryBuilder::::default() .with_type(LocationType::Shop) .with_name(&req.shop_name) .with_owner(user.id.unwrap()); let mut shop = ctx .db .run_query(query)? .pop() .ok_or(GeoffreyAPIError::EntryNotFound)?; if let LocationDataDb::Shop(shop_data) = &mut shop.loc_data { let filter = regex::RegexBuilder::new(&req.item_name) .case_insensitive(true) .build() .map_err(|e| GeoffreyAPIError::InvalidRegex(e.to_string()))?; let updated_items: HashSet = shop_data .item_listings .iter() .map(|item| { let mut item = item.clone(); if filter.is_match(&item.item.name) { item.restock(); } item }) .collect(); shop_data.item_listings = updated_items; let shop = ctx.db.insert(shop)?; load_location(&ctx.db, &shop).map_err(|err| err.into()) } else { Err(GeoffreyAPIError::EntryNotFound) } } }