diff --git a/src/framework/commands/mod.rs b/src/framework/commands/mod.rs index 22cb951..051a22e 100644 --- a/src/framework/commands/mod.rs +++ b/src/framework/commands/mod.rs @@ -9,6 +9,7 @@ pub mod arguments; pub mod context; pub mod messages; pub mod runner; +pub mod permissions; #[derive(Debug, Error)] pub enum CommandError { @@ -37,6 +38,9 @@ pub trait Command: Send + Sync + Debug { fn arguments(&self) -> &'static [Argument] { &[] } + fn permissions(&self) -> &'static [Box + Send + Sync>] { + &[] + } /// Returns the command name + all its aliases. /// diff --git a/src/framework/commands/permissions.rs b/src/framework/commands/permissions.rs new file mode 100644 index 0000000..452cf73 --- /dev/null +++ b/src/framework/commands/permissions.rs @@ -0,0 +1,10 @@ +use std::fmt::Debug; + +use async_trait::async_trait; + +use crate::framework::commands::{CommandError, context::CommandContext}; + +#[async_trait] +pub trait Permission: Debug { + async fn check(&self, ctx: &CommandContext) -> Result; +} diff --git a/src/framework/commands/runner.rs b/src/framework/commands/runner.rs index b1e8b1e..65c4b48 100644 --- a/src/framework/commands/runner.rs +++ b/src/framework/commands/runner.rs @@ -31,12 +31,21 @@ impl OnMessageHandler for CommandRunner { }); if let Some(command) = command { - command - .execute( - CommandContext::new(event, rt.clone(), &prefixes[0]), - parts.args, - ) - .await?; + let ctx = CommandContext::new(event, rt.clone(), &prefixes[0]); + + for permission in command.permissions() { + if !permission + .check(&ctx) + .await + .inspect_err(|e| log::error!("Permission check failed: {e}"))? + { + return Err( + format!("The check for permission {permission:?} failed").into() + ); + } + } + + command.execute(ctx, parts.args).await?; break; }