Added delete command to bot
continuous-integration/woodpecker the build was successful Details

+ Added more error messages
+ Added lang.rs to store common messages
+ clippy + fmt
main
Joey Hines 2021-12-18 09:43:59 -07:00
parent 551a0a7618
commit 37117ce5a9
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
6 changed files with 107 additions and 16 deletions

View File

@ -9,6 +9,7 @@ use geoffrey_models::models::parameters::add_item_params::AddItemParams;
use crate::bot::arg_parse::{option_to_i64, option_to_string}; use crate::bot::arg_parse::{option_to_i64, option_to_string};
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::lang::{PLAYER_ALREADY_SELLS_ITEM, PLAYER_DOES_NOT_HAVE_MATCHING_SHOP};
use geoffrey_models::models::response::api_error::GeoffreyAPIError; use geoffrey_models::models::response::api_error::GeoffreyAPIError;
use serenity::builder::CreateApplicationCommand; use serenity::builder::CreateApplicationCommand;
@ -28,19 +29,28 @@ impl BotCommand for AddItemCommand {
} }
fn custom_err_resp(e: &CommandError) -> Option<String> { fn custom_err_resp(e: &CommandError) -> Option<String> {
if let CommandError::GeoffreyApi(err) = e { match e {
if matches!(err, GeoffreyAPIError::EntryNotFound) { CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotFound) => {
return Some("You don't have a shop by that name ding dong!".to_string()); Some(PLAYER_DOES_NOT_HAVE_MATCHING_SHOP.to_string())
} }
CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotUnique) => {
Some(PLAYER_ALREADY_SELLS_ITEM.to_string())
}
_ => None,
} }
None
} }
fn create_app_command(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { fn create_app_command(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand {
command command
.name(Self::command_name()) .name(Self::command_name())
.description("Add a item to a shop.") .description("Add a item to a shop.")
.create_option(|option| {
option
.name("shop")
.description("Shop to list the item at")
.kind(ApplicationCommandOptionType::String)
.required(true)
})
.create_option(|option| { .create_option(|option| {
option option
.name("item_name") .name("item_name")
@ -64,13 +74,6 @@ impl BotCommand for AddItemCommand {
.required(true) .required(true)
.min_int_value(1) .min_int_value(1)
}) })
.create_option(|option| {
option
.name("shop")
.description("Shop to list the item at")
.kind(ApplicationCommandOptionType::String)
.required(true)
})
} }
async fn process_arguments( async fn process_arguments(
@ -79,10 +82,10 @@ impl BotCommand for AddItemCommand {
let options = command_interaction.data.options; let options = command_interaction.data.options;
Ok(Self::ApiParams::new( Ok(Self::ApiParams::new(
option_to_string(options.get(0), "item_name")?, option_to_string(options.get(1), "item_name")?,
option_to_i64(options.get(1), "price")? as u32, option_to_i64(options.get(2), "price")? as u32,
option_to_i64(options.get(2), "quantity")? as u32, option_to_i64(options.get(3), "quantity")? as u32,
option_to_string(options.get(3), "shop")?, option_to_string(options.get(0), "shop")?,
)) ))
} }

View File

@ -0,0 +1,67 @@
use async_trait::async_trait;
use geoffrey_models::models::locations::Location;
use reqwest::Method;
use serenity::model::interactions::application_command::{
ApplicationCommandInteraction, ApplicationCommandOptionType,
};
use crate::bot::arg_parse::option_to_string;
use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC;
use geoffrey_models::models::parameters::delete_params::DeleteParams;
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
use serenity::builder::CreateApplicationCommand;
pub struct DeleteCommand;
#[async_trait]
impl BotCommand for DeleteCommand {
type ApiParams = DeleteParams;
type ApiResp = Location;
fn command_name() -> String {
"delete".to_string()
}
fn request_type() -> Method {
Method::POST
}
fn custom_err_resp(err: &CommandError) -> Option<String> {
match err {
CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotFound) => {
Some(PLAYER_DOES_NOT_HAVE_MATCHING_LOC.to_string())
}
_ => None,
}
}
fn create_app_command(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand {
command
.name(Self::command_name())
.description("Delete a location from Geoffrey")
.create_option(|option| {
option
.name("loc_name")
.description("Name of the location")
.kind(ApplicationCommandOptionType::String)
.required(true)
})
}
async fn process_arguments(
command_interaction: ApplicationCommandInteraction,
) -> Result<Self::ApiParams, CommandError> {
let options = command_interaction.data.options;
let loc_name = option_to_string(options.get(0), "loc_name")?;
Ok(Self::ApiParams::new(loc_name))
}
fn build_response(resp: Self::ApiResp) -> String {
format!(
"{} has been been removed from Geoffrey, good riddance!",
resp.name
)
}
}

View File

@ -19,6 +19,7 @@ use std::pin::Pin;
pub mod add_item; pub mod add_item;
pub mod add_location; pub mod add_location;
pub mod delete;
pub mod find; pub mod find;
pub mod selling; pub mod selling;
pub mod set_portal; pub mod set_portal;

View File

@ -8,7 +8,9 @@ use serenity::model::interactions::application_command::{
use crate::bot::arg_parse::{option_to_i64, option_to_string}; use crate::bot::arg_parse::{option_to_i64, option_to_string};
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC;
use geoffrey_models::models::parameters::set_portal_params::SetPortalParams; use geoffrey_models::models::parameters::set_portal_params::SetPortalParams;
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
use serenity::builder::CreateApplicationCommand; use serenity::builder::CreateApplicationCommand;
pub struct SetPortalCommand; pub struct SetPortalCommand;
@ -26,6 +28,15 @@ impl BotCommand for SetPortalCommand {
Method::POST Method::POST
} }
fn custom_err_resp(err: &CommandError) -> Option<String> {
match err {
CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotFound) => {
Some(PLAYER_DOES_NOT_HAVE_MATCHING_LOC.to_string())
}
_ => None,
}
}
fn create_app_command(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { fn create_app_command(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand {
command command
.name(Self::command_name()) .name(Self::command_name())

View File

@ -0,0 +1,5 @@
pub const PLAYER_DOES_NOT_HAVE_MATCHING_LOC: &str =
"You don't have a location by that name, try again slugger.";
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";

View File

@ -1,6 +1,7 @@
use serenity::model::interactions::application_command::ApplicationCommand; use serenity::model::interactions::application_command::ApplicationCommand;
use serenity::prelude::*; use serenity::prelude::*;
use crate::bot::commands::delete::DeleteCommand;
use crate::bot::commands::GeoffreyCommandFn; use crate::bot::commands::GeoffreyCommandFn;
use crate::context::GeoffreyContext; use crate::context::GeoffreyContext;
use commands::add_item::AddItemCommand; use commands::add_item::AddItemCommand;
@ -16,6 +17,7 @@ use std::collections::HashMap;
pub mod arg_parse; pub mod arg_parse;
pub mod commands; pub mod commands;
pub mod formatters; pub mod formatters;
mod lang;
#[derive(Default)] #[derive(Default)]
pub struct CommandRunner { pub struct CommandRunner {
@ -76,6 +78,8 @@ pub async fn build_commands(
.add_command::<SellingCommand>(ctx) .add_command::<SellingCommand>(ctx)
.await? .await?
.add_command::<SetPortalCommand>(ctx) .add_command::<SetPortalCommand>(ctx)
.await?
.add_command::<DeleteCommand>(ctx)
.await?; .await?;
Ok(()) Ok(())