use async_trait::async_trait; use reqwest::Method; use serenity::client::Context; use serenity::model::interactions::application_command::{ ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType, }; use serenity::model::prelude::application_command::ApplicationCommandInteractionDataOptionValue; use geoffrey_models::models::locations::Location; use geoffrey_models::models::parameters::add_item_params::AddItemParams; use crate::bot::commands::{BotCommand, CommandError}; pub struct AddItemCommand; #[async_trait] impl BotCommand for AddItemCommand { type ApiParams = AddItemParams; type ApiResp = Location; fn command_name() -> String { "add_item".to_string() } fn request_type() -> Method { Method::POST } async fn create_app_command(ctx: &Context) -> Result { let command = ApplicationCommand::create_global_application_command(&ctx.http, |command| { command .name(Self::command_name()) .description("Add a item to a shop.") .create_option(|option| { option .name("item_name") .description("Name of the item to sell.") .kind(ApplicationCommandOptionType::String) .required(true) }) .create_option(|option| { option .name("price") .description("Price to list them item at.") .kind(ApplicationCommandOptionType::Integer) .required(true) .min_int_value(0) }) .create_option(|option| { option .name("quantity") .description("Number of items to sell for price") .kind(ApplicationCommandOptionType::Integer) .required(true) .min_int_value(1) }) .create_option(|option| { option .name("shop") .description("Shop to list the item at") .kind(ApplicationCommandOptionType::String) .required(true) }) }) .await?; Ok(command) } async fn process_arguments( command_interaction: ApplicationCommandInteraction, ) -> Result { let options = command_interaction.data.options; let mut item_name = String::default(); let mut price = 0; let mut quanity = 0; let mut shop = String::default(); if let Some(option) = options.get(0) { let option = option.resolved.as_ref(); if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { item_name = s.clone(); } else { return Err(CommandError::ArgumentParse("item_name".to_string())); } } if let Some(option) = options.get(1) { let option = option.resolved.as_ref(); if let Some(ApplicationCommandInteractionDataOptionValue::Integer(p)) = option { price = *p; } else { return Err(CommandError::ArgumentParse("price".to_string())); } } if let Some(option) = options.get(2) { let option = option.resolved.as_ref(); if let Some(ApplicationCommandInteractionDataOptionValue::Integer(q)) = option { quanity = *q; } else { return Err(CommandError::ArgumentParse("quantity".to_string())); } } if let Some(option) = options.get(3) { let option = option.resolved.as_ref(); if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { shop = s.clone(); } else { return Err(CommandError::ArgumentParse("shop".to_string())); } } Ok(Self::ApiParams::new( item_name, price as u32, quanity as u32, shop, )) } fn build_response(resp: Self::ApiResp) -> String { format!("{} has been updated", resp.name) } }