use serenity::model::interactions::application_command::ApplicationCommand; use serenity::prelude::*; use crate::bot::commands::delete::DeleteCommand; use crate::bot::commands::GeoffreyCommandFn; use crate::context::GeoffreyContext; use commands::add_item::AddItemCommand; use commands::add_location::AddLocationCommand; use commands::find::FindCommand; use commands::selling::SellingCommand; use commands::set_portal::SetPortalCommand; use commands::{BotCommand, CommandError}; use geoffrey_models::models::player::UserID; use serenity::model::prelude::application_command::ApplicationCommandInteraction; use std::collections::HashMap; pub mod arg_parse; pub mod commands; pub mod formatters; mod lang; #[derive(Default)] pub struct CommandRunner { commands: HashMap, } impl CommandRunner { async fn register_app_command(ctx: &Context) -> Result<(), CommandError> { ApplicationCommand::create_global_application_command(&ctx.http, |command| { T::create_app_command(command) }) .await?; Ok(()) } fn add_command_to_lookup(&mut self) { self.commands .insert(T::command_name(), Box::new(T::command)); } pub async fn add_command( &mut self, ctx: &Context, ) -> Result<&mut Self, CommandError> { self.add_command_to_lookup::(); Self::register_app_command::(ctx).await?; Ok(self) } pub async fn run_command<'r>( &self, command_name: &str, geoffrey_ctx: GeoffreyContext, user_id: UserID, interaction: ApplicationCommandInteraction, ) -> Result { let command_fn = self .commands .get(command_name) .ok_or_else(|| CommandError::CommandNotFound(command_name.to_string()))?; Ok(command_fn(geoffrey_ctx, user_id, interaction).await) } } pub async fn build_commands( ctx: &Context, command_runner: &mut CommandRunner, ) -> Result<(), CommandError> { command_runner .add_command::(ctx) .await? .add_command::(ctx) .await? .add_command::(ctx) .await? .add_command::(ctx) .await? .add_command::(ctx) .await? .add_command::(ctx) .await?; Ok(()) } impl TypeMapKey for CommandRunner { type Value = CommandRunner; }