use std::collections::HashSet; use std::sync::Arc; use serenity::framework::standard::macros::help; use serenity::framework::standard::macros::hook; use serenity::framework::standard::{ help_commands, Args, CommandError, CommandGroup, CommandResult, HelpOptions, }; use serenity::model::id::UserId; use serenity::model::prelude::Message; use serenity::prelude::Context; use serenity::prelude::{TypeMap, TypeMapKey}; use tokio::sync::RwLockReadGuard; use crate::database::models::Event; use crate::database::Database; pub mod events; pub mod handler; pub mod tasks; pub mod utility; /// Struct for storing drafted events #[derive(Debug, Clone, Default)] pub struct DraftEvent { pub event: Event, pub creator_id: u64, } impl TypeMapKey for DraftEvent { type Value = Arc; } /// Gets the draft event from context data pub async fn get_draft_event( data: &RwLockReadGuard<'_, TypeMap>, ) -> std::result::Result, CommandError> { let draft_event = data .get::() .ok_or_else(|| CommandError::from("Unable to get queued event".to_string()))?; Ok(draft_event.clone()) } /// Gets the database from context data pub async fn get_db( data: &RwLockReadGuard<'_, TypeMap>, ) -> std::result::Result, CommandError> { let db = data .get::() .ok_or_else(|| CommandError::from("Unable to get db".to_string()))?; Ok(db.clone()) } /// Logs command errors to the logger #[hook] pub async fn log_error( _ctx: &Context, _msg: &Message, command_name: &str, result: std::result::Result<(), CommandError>, ) { match result { Ok(()) => (), Err(why) => error!("Command '{}' returned error {:?}", command_name, why), }; } /// Checks if the user has permission to use this bot #[hook] pub async fn permission_check(ctx: &Context, msg: &Message, _command_name: &str) -> bool { if let Some(guild_id) = msg.guild_id { if let Ok(config) = utility::get_config(&ctx.data.read().await).await { if let Ok(roles) = ctx.http.get_guild_roles(guild_id.0).await { for role in roles { if config.event_roles.contains(&role.id.0) { return msg .author .has_role(&ctx, guild_id, role) .await .unwrap_or(false) } } } } } false } #[help] #[command_not_found_text = "Could not find: `{}`."] #[strikethrough_commands_tip_in_guild("")] async fn bot_help( context: &Context, msg: &Message, args: Args, help_options: &'static HelpOptions, groups: &[&'static CommandGroup], owners: HashSet, ) -> CommandResult { help_commands::with_embeds(context, msg, args, help_options, groups, owners).await; Ok(()) }