From e748d1ff80dbbeb82b23f8ac9fec9cf8c7e4a69e Mon Sep 17 00:00:00 2001 From: acdenisSK Date: Sat, 18 Nov 2017 12:06:22 +0100 Subject: Add `cmd` to `Create(Command|Group)` --- src/framework/standard/create_command.rs | 41 +++++++++++++++++++++++--------- src/framework/standard/create_group.rs | 23 +++++++++++++----- src/framework/standard/mod.rs | 4 ++-- 3 files changed, 49 insertions(+), 19 deletions(-) (limited to 'src/framework') diff --git a/src/framework/standard/create_command.rs b/src/framework/standard/create_command.rs index e5c9208..4137b91 100644 --- a/src/framework/standard/create_command.rs +++ b/src/framework/standard/create_command.rs @@ -4,7 +4,12 @@ use client::Context; use model::{Message, Permissions}; use std::sync::Arc; -pub struct CreateCommand(pub CommandOptions, pub fn(&mut Context, &Message, Args) -> Result<(), CommandError>); +pub enum FnOrCommand { + Fn(fn(&mut Context, &Message, Args) -> Result<(), CommandError>), + Command(Arc), +} + +pub struct CreateCommand(pub CommandOptions, pub FnOrCommand); impl CreateCommand { /// Adds multiple aliases. @@ -104,10 +109,19 @@ impl CreateCommand { /// A function that can be called when a command is received. /// You can return `Err(string)` if there's an error. pub fn exec(mut self, func: fn(&mut Context, &Message, Args) -> Result<(), CommandError>) -> Self { - self.1 = func; + self.1 = FnOrCommand::Fn(func); self } + + /// Like [`exec`] but accepts a `Command` directly. + /// + /// [`exec`]: #method.exec + pub fn cmd(mut self, c: C) -> Self { + self.1 = FnOrCommand::Command(Arc::new(c)); + + self + } /// Whether command can be used only in guilds or not. pub fn guild_only(mut self, guild_only: bool) -> Self { @@ -182,19 +196,24 @@ impl CreateCommand { } pub(crate) fn finish(self) -> Arc { - let CreateCommand(options, func) = self; + let CreateCommand(options, fc) = self; - struct A(Arc, fn(&mut Context, &Message, Args) -> Result<(), CommandError>); + match fc { + FnOrCommand::Fn(func) => { + struct A(Arc, fn(&mut Context, &Message, Args) -> Result<(), CommandError>); - impl Command for A { - fn execute(&self, c: &mut Context, m: &Message, a: Args) -> Result<(), CommandError> { - (self.1)(c, m, a) - } + impl Command for A { + fn execute(&self, c: &mut Context, m: &Message, a: Args) -> Result<(), CommandError> { + (self.1)(c, m, a) + } - fn options(&self) -> Arc { Arc::clone(&self.0) } - } + fn options(&self) -> Arc { Arc::clone(&self.0) } + } - Arc::new(A(Arc::new(options), func)) + Arc::new(A(Arc::new(options), func)) + }, + FnOrCommand::Command(cmd) => cmd, + } } } diff --git a/src/framework/standard/create_group.rs b/src/framework/standard/create_group.rs index f9097e6..7d7cc36 100644 --- a/src/framework/standard/create_group.rs +++ b/src/framework/standard/create_group.rs @@ -1,7 +1,7 @@ pub use super::command::{Command, CommandGroup, CommandOptions, Error as CommandError}; pub(crate) use super::command::CommandOrAlias; pub(crate) use super::command::A; -pub use super::create_command::CreateCommand; +pub use super::create_command::{CreateCommand, FnOrCommand}; pub use super::Args; use client::Context; @@ -27,7 +27,7 @@ pub struct CreateGroup(pub CommandGroup); impl CreateGroup { fn build_command(&self) -> CreateCommand { - let mut cmd = CreateCommand(CommandOptions::default(), |_, _, _| Ok(())) + let mut cmd = CreateCommand(CommandOptions::default(), FnOrCommand::Fn(|_, _, _| Ok(()))) .required_permissions(self.0.required_permissions) .dm_only(self.0.dm_only) .guild_only(self.0.guild_only) @@ -70,16 +70,27 @@ impl CreateGroup { /// Adds a command to group with simplified API. /// You can return Err(From::from(string)) if there's an error. - pub fn on(mut self, name: &str, + pub fn on(self, name: &str, f: fn(&mut Context, &Message, Args) -> Result<(), CommandError>) -> Self { - let cmd = Arc::new(A(f)); - + self._cmd(name, A(f)) + } + + /// Like [`on`], but accepts a `Command` directly. + /// + /// [`on`]: #method.on + pub fn cmd(self, name: &str, c: C) -> Self { + self._cmd(name, c) + } + + fn _cmd(mut self, name: &str, c: C) -> Self { + let cmd = Arc::new(c); + self.0 .commands .insert(name.to_string(), CommandOrAlias::Command(cmd)); self - } + } /// If prefix is set, it will be required before all command names. /// For example, if bot prefix is "~" and group prefix is "image" diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs index 792814e..2f7429b 100644 --- a/src/framework/standard/mod.rs +++ b/src/framework/standard/mod.rs @@ -14,7 +14,7 @@ pub(crate) use self::command::{A, Help}; pub use self::command::{Command, CommandGroup, CommandOptions, Error as CommandError}; pub use self::command::CommandOrAlias; pub use self::configuration::Configuration; -pub use self::create_command::CreateCommand; +pub use self::create_command::{CreateCommand, FnOrCommand}; pub use self::create_group::CreateGroup; use client::Context; @@ -682,7 +682,7 @@ impl StandardFramework { .or_insert_with(|| Arc::new(CommandGroup::default())); if let Some(ref mut group) = Arc::get_mut(ungrouped) { - let cmd = f(CreateCommand(CommandOptions::default(), |_, _, _| Ok(()))).finish(); + let cmd = f(CreateCommand(CommandOptions::default(), FnOrCommand::Fn(|_, _, _| Ok(())))).finish(); let name = command_name.to_string(); if let Some(ref prefix) = group.prefix { -- cgit v1.2.3