Geoffrey-rs/geoffrey_bot/src/bot/mod.rs

112 lines
3.2 KiB
Rust

use serenity::model::interactions::application_command::ApplicationCommand;
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;
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<String, GeoffreyCommandFn>,
pub app_commands: Vec<ApplicationCommand>,
}
impl CommandRunner {
async fn register_app_command<T: BotCommand>(
&mut self,
ctx: &Context,
) -> Result<(), CommandError> {
let command = ApplicationCommand::create_global_application_command(&ctx.http, |command| {
T::create_app_command(command)
})
.await?;
self.app_commands.push(command);
Ok(())
}
fn add_command_to_lookup<T: BotCommand>(&mut self) {
self.commands
.insert(T::command_name(), Box::new(T::command));
}
pub async fn add_command<T: BotCommand>(
&mut self,
ctx: &Context,
) -> Result<&mut Self, CommandError> {
self.add_command_to_lookup::<T>();
self.register_app_command::<T>(ctx).await?;
Ok(self)
}
pub async fn run_command<'r>(
&self,
command_name: &str,
geoffrey_ctx: GeoffreyContext,
user_id: UserID,
interaction: ApplicationCommandInteraction,
) -> Result<String, CommandError> {
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::<AddItemCommand>(ctx)
.await?
.add_command::<AddLocationCommand>(ctx)
.await?
.add_command::<FindCommand>(ctx)
.await?
.add_command::<SellingCommand>(ctx)
.await?
.add_command::<SetPortalCommand>(ctx)
.await?
.add_command::<DeleteCommand>(ctx)
.await?
.add_command::<RegisterCommand>(ctx)
.await?
.add_command::<EditPosCommand>(ctx)
.await?
.add_command::<EditNameCommand>(ctx)
.await?
.add_command::<RemoveItemCommand>(ctx)
.await?
.add_command::<InfoCommand>(ctx)
.await?;
Ok(())
}
impl TypeMapKey for CommandRunner {
type Value = CommandRunner;
}