diff --git a/geoffrey_api/src/commands/info.rs b/geoffrey_api/src/commands/info.rs new file mode 100644 index 0000000..73b715d --- /dev/null +++ b/geoffrey_api/src/commands/info.rs @@ -0,0 +1,46 @@ +use crate::commands::{Command, RequestType}; +use crate::context::Context; +use crate::Result; +use geoffrey_db::helper::load_location; +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; + +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 = req.location_name.to_lowercase(); + + let location: LocationDb = ctx + .db + .filter(|_, loc: &LocationDb| { + let name = loc.name.to_lowercase(); + + name == query + }) + .map_err(GeoffreyAPIError::from)? + .next() + .ok_or(GeoffreyAPIError::EntryNotFound)?; + + Ok(load_location(&ctx.db, &location)?) + } +} diff --git a/geoffrey_api/src/commands/mod.rs b/geoffrey_api/src/commands/mod.rs index 67f600f..d305715 100644 --- a/geoffrey_api/src/commands/mod.rs +++ b/geoffrey_api/src/commands/mod.rs @@ -3,6 +3,7 @@ use crate::commands::add_location::AddLocation; use crate::commands::delete::Delete; use crate::commands::edit::Edit; use crate::commands::find::FindCommand; +use crate::commands::info::InfoCommand; use crate::commands::link::LinkCommand; use crate::commands::register::Register; use crate::commands::remove_item::RemoveItem; @@ -30,6 +31,7 @@ pub mod add_token; pub mod delete; pub mod edit; pub mod find; +pub mod info; pub mod link; pub mod register; pub mod remove_item; @@ -140,6 +142,7 @@ pub fn command_filter( .or(create_command_filter::(ctx.clone())) .or(create_command_filter::(ctx.clone())) .or(create_command_filter::(ctx.clone())) + .or(create_command_filter::(ctx.clone())) .or(create_command_filter::(ctx)), ) } diff --git a/geoffrey_bot/src/bot/commands/info.rs b/geoffrey_bot/src/bot/commands/info.rs new file mode 100644 index 0000000..e2a6c52 --- /dev/null +++ b/geoffrey_bot/src/bot/commands/info.rs @@ -0,0 +1,66 @@ +use async_trait::async_trait; +use reqwest::Method; +use serenity::model::interactions::application_command::{ + ApplicationCommandInteraction, ApplicationCommandOptionType, +}; + +use geoffrey_models::models::locations::Location; + +use crate::bot::arg_parse::option_to_string; +use crate::bot::commands::{BotCommand, CommandError}; +use crate::bot::formatters::display_loc_full; +use crate::bot::lang::NO_LOCATION_FOUND; +use geoffrey_models::models::parameters::info_params::InfoParams; +use geoffrey_models::models::response::api_error::GeoffreyAPIError; +use serenity::builder::CreateApplicationCommand; + +pub struct InfoCommand; + +#[async_trait] +impl BotCommand for InfoCommand { + type ApiParams = InfoParams; + type ApiResp = Location; + + fn command_name() -> String { + "info".to_string() + } + + fn request_type() -> Method { + Method::GET + } + + fn custom_err_resp(err: &CommandError) -> Option { + match err { + CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotFound) => { + Some(NO_LOCATION_FOUND.to_string()) + } + _ => None, + } + } + + fn create_app_command(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { + command + .name(Self::command_name()) + .description("Get info on a location in Geoffrey.") + .create_option(|option| { + option + .name("loc_name") + .description("The location to get info on") + .kind(ApplicationCommandOptionType::String) + .required(true) + }) + } + + async fn process_arguments( + command_interaction: ApplicationCommandInteraction, + ) -> Result { + let options = command_interaction.data.options; + let location_name = option_to_string(options.get(0), "loc_name")?; + + Ok(Self::ApiParams::new(location_name)) + } + + fn build_response(resp: Self::ApiResp) -> String { + display_loc_full(&resp) + } +} diff --git a/geoffrey_bot/src/bot/commands/mod.rs b/geoffrey_bot/src/bot/commands/mod.rs index 9fb4afc..74ff59b 100644 --- a/geoffrey_bot/src/bot/commands/mod.rs +++ b/geoffrey_bot/src/bot/commands/mod.rs @@ -23,6 +23,7 @@ pub mod delete; pub mod edit_name; pub mod edit_pos; pub mod find; +pub mod info; pub mod register; pub mod remove_item; pub mod selling; diff --git a/geoffrey_bot/src/bot/lang.rs b/geoffrey_bot/src/bot/lang.rs index 7f1bd57..722718d 100644 --- a/geoffrey_bot/src/bot/lang.rs +++ b/geoffrey_bot/src/bot/lang.rs @@ -3,3 +3,4 @@ pub const PLAYER_DOES_NOT_HAVE_MATCHING_LOC: &str = pub const PLAYER_DOES_NOT_HAVE_MATCHING_SHOP: &str = "You don't have a shop by that name, try again champ."; pub const PLAYER_ALREADY_SELLS_ITEM: &str = "You already sell that ding dong"; +pub const NO_LOCATION_FOUND: &str = "No location found by that name goober"; diff --git a/geoffrey_bot/src/bot/mod.rs b/geoffrey_bot/src/bot/mod.rs index f882b94..bd6100f 100644 --- a/geoffrey_bot/src/bot/mod.rs +++ b/geoffrey_bot/src/bot/mod.rs @@ -4,6 +4,7 @@ use serenity::prelude::*; use crate::bot::commands::delete::DeleteCommand; use crate::bot::commands::edit_name::EditNameCommand; use crate::bot::commands::edit_pos::EditPosCommand; +use crate::bot::commands::info::InfoCommand; use crate::bot::commands::register::RegisterCommand; use crate::bot::commands::remove_item::RemoveItemCommand; use crate::bot::commands::GeoffreyCommandFn; @@ -98,6 +99,8 @@ pub async fn build_commands( .add_command::(ctx) .await? .add_command::(ctx) + .await? + .add_command::(ctx) .await?; Ok(()) diff --git a/geoffrey_models/src/models/parameters/info_params.rs b/geoffrey_models/src/models/parameters/info_params.rs new file mode 100644 index 0000000..fcb51e6 --- /dev/null +++ b/geoffrey_models/src/models/parameters/info_params.rs @@ -0,0 +1,15 @@ +use crate::models::parameters::GeoffreyParam; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct InfoParams { + pub location_name: String, +} + +impl InfoParams { + pub fn new(location_name: String) -> Self { + Self { location_name } + } +} + +impl GeoffreyParam for InfoParams {} diff --git a/geoffrey_models/src/models/parameters/mod.rs b/geoffrey_models/src/models/parameters/mod.rs index 2a26399..5c3a86f 100644 --- a/geoffrey_models/src/models/parameters/mod.rs +++ b/geoffrey_models/src/models/parameters/mod.rs @@ -4,6 +4,7 @@ pub mod add_token_params; pub mod delete_params; pub mod edit_params; pub mod find_params; +pub mod info_params; pub mod link_params; pub mod register_params; pub mod remove_item_params;