diff options
| author | acdenisSK <[email protected]> | 2017-08-20 23:02:38 +0200 |
|---|---|---|
| committer | acdenisSK <[email protected]> | 2017-08-20 23:05:34 +0200 |
| commit | 45d72eff173d87b1353d8b5d001775cc49129dab (patch) | |
| tree | 5ecfdf54bbaeb597bd557c0307ddfd6392b7860e /src/framework | |
| parent | Use wildcard (diff) | |
| download | serenity-45d72eff173d87b1353d8b5d001775cc49129dab.tar.xz serenity-45d72eff173d87b1353d8b5d001775cc49129dab.zip | |
Revamp the args to an `Args` struct
Fixes #142
Diffstat (limited to 'src/framework')
| -rw-r--r-- | src/framework/standard/command.rs | 13 | ||||
| -rw-r--r-- | src/framework/standard/create_command.rs | 33 | ||||
| -rw-r--r-- | src/framework/standard/create_group.rs | 3 | ||||
| -rw-r--r-- | src/framework/standard/help_commands.rs | 10 | ||||
| -rw-r--r-- | src/framework/standard/mod.rs | 121 |
5 files changed, 41 insertions, 139 deletions
diff --git a/src/framework/standard/command.rs b/src/framework/standard/command.rs index 01c4c5e..d8c2321 100644 --- a/src/framework/standard/command.rs +++ b/src/framework/standard/command.rs @@ -1,15 +1,15 @@ use std::sync::Arc; -use super::Configuration; +use super::{Configuration, Args}; use client::Context; use model::{Message, Permissions}; use std::collections::HashMap; -pub type Check = Fn(&mut Context, &Message, &[String], &Arc<Command>) -> bool + 'static; -pub type Exec = Fn(&mut Context, &Message, Vec<String>, String) -> Result<(), String> + 'static; +pub type Check = Fn(&mut Context, &Message, &mut Args, &Arc<Command>) -> bool + 'static; +pub type Exec = Fn(&mut Context, &Message, Args) -> Result<(), String> + 'static; pub type Help = Fn(&mut Context, &Message, HashMap<String, Arc<CommandGroup>>, - &[String]) + Args) -> Result<(), String> + 'static; pub type BeforeHook = Fn(&mut Context, &Message, &str) -> bool + 'static; @@ -51,8 +51,6 @@ pub struct Command { pub example: Option<String>, /// Command usage schema, used by other commands. pub usage: Option<String>, - /// Whether arguments should be parsed using quote parser or not. - pub use_quotes: bool, /// Minumum amount of arguments that should be passed. pub min_args: Option<i32>, /// Maximum amount of arguments that can be passed. @@ -72,7 +70,7 @@ pub struct Command { impl Command { pub fn new<F>(f: F) -> Self - where F: Fn(&mut Context, &Message, Vec<String>, String) -> Result<(), String> + 'static { + where F: Fn(&mut Context, &Message, Args) -> Result<(), String> + 'static { Command { aliases: Vec::new(), checks: Vec::default(), @@ -80,7 +78,6 @@ impl Command { desc: None, usage: None, example: None, - use_quotes: false, dm_only: false, bucket: None, guild_only: false, diff --git a/src/framework/standard/create_command.rs b/src/framework/standard/create_command.rs index 160a508..f6be992 100644 --- a/src/framework/standard/create_command.rs +++ b/src/framework/standard/create_command.rs @@ -1,4 +1,4 @@ -pub use super::{Command, CommandGroup, CommandType}; +pub use super::{Args, Command, CommandGroup, CommandType}; use std::collections::HashMap; use std::default::Default; @@ -52,22 +52,21 @@ impl CreateCommand { /// .desc("Replies to a ping with a pong") /// .exec(ping))); /// - /// fn ping(_context: &mut Context, message: &Message, _args: Vec<String>, _original_msg: - /// String) -> Result<(), + /// fn ping(_context: &mut Context, message: &Message, _args: Args) -> Result<(), /// String> { /// let _ = message.channel_id.say("Pong!"); /// /// Ok(()) /// } /// - /// fn owner_check(_context: &mut Context, message: &Message, _: &[String], _: + /// fn owner_check(_context: &mut Context, message: &Message, _: &mut Args, _: /// &Arc<Command>) -> bool { /// // replace with your user ID /// message.author.id == 7 /// } /// ``` pub fn check<F>(mut self, check: F) -> Self - where F: Fn(&mut Context, &Message, &[String], &Arc<Command>) -> bool + where F: Fn(&mut Context, &Message, &mut Args, &Arc<Command>) -> bool + Send + Sync + 'static { @@ -104,7 +103,7 @@ impl CreateCommand { /// /// [`exec_str`]: #method.exec_str pub fn exec<F>(mut self, func: F) -> Self - where F: Fn(&mut Context, &Message, Vec<String>, String) -> Result<(), String> + where F: Fn(&mut Context, &Message, Args) -> Result<(), String> + Send + Sync + 'static { @@ -122,7 +121,7 @@ impl CreateCommand { where F: Fn(&mut Context, &Message, HashMap<String, Arc<CommandGroup>>, - &[String]) + Args) -> Result<(), String> + 'static { self.0.exec = CommandType::WithCommands(Box::new(f)); @@ -203,23 +202,6 @@ impl CreateCommand { self } - - /// Whether or not arguments should be parsed using the quotation parser. - /// - /// Enabling this will parse `~command "this is arg 1" "this is arg 2"` as - /// two arguments: `this is arg 1` and `this is arg 2`. - /// - /// Disabling this will parse `~command "this is arg 1" "this is arg 2"` as - /// eight arguments: `"this`, `is`, `arg`, `1"`, `"this`, `is`, `arg`, `2"`. - /// - /// Refer to [`utils::parse_quotes`] for information on the parser. - /// - /// [`utils::parse_quotes`]: ../../utils/fn.parse_quotes.html - pub fn use_quotes(mut self, use_quotes: bool) -> Self { - self.0.use_quotes = use_quotes; - - self - } } impl Default for Command { @@ -227,11 +209,10 @@ impl Default for Command { Command { aliases: Vec::new(), checks: Vec::default(), - exec: CommandType::Basic(Box::new(|_, _, _, _| Ok(()))), + exec: CommandType::Basic(Box::new(|_, _, _| Ok(()))), desc: None, usage: None, example: None, - use_quotes: false, min_args: None, bucket: None, max_args: None, diff --git a/src/framework/standard/create_group.rs b/src/framework/standard/create_group.rs index b45c41e..fabcc50 100644 --- a/src/framework/standard/create_group.rs +++ b/src/framework/standard/create_group.rs @@ -1,6 +1,7 @@ pub use super::command::{Command, CommandGroup, CommandType}; pub(crate) use super::command::CommandOrAlias; pub use super::create_command::CreateCommand; +pub use super::Args; use std::default::Default; use std::sync::Arc; @@ -57,7 +58,7 @@ impl CreateGroup { /// Adds a command to group with simplified API. /// You can return Err(string) if there's an error. pub fn on<F>(mut self, command_name: &str, f: F) -> Self - where F: Fn(&mut Context, &Message, Vec<String>, String) -> Result<(), String> + where F: Fn(&mut Context, &Message, Args) -> Result<(), String> + Send + Sync + 'static { diff --git a/src/framework/standard/help_commands.rs b/src/framework/standard/help_commands.rs index a7c20fd..f081e1a 100644 --- a/src/framework/standard/help_commands.rs +++ b/src/framework/standard/help_commands.rs @@ -27,7 +27,7 @@ use std::collections::HashMap; use std::sync::Arc; use std::fmt::Write; use super::command::InternalCommand; -use super::{Command, CommandGroup, CommandOrAlias}; +use super::{Args, Command, CommandGroup, CommandOrAlias}; use client::Context; use model::{ChannelId, Message}; use utils::Colour; @@ -71,10 +71,10 @@ fn remove_aliases(cmds: &HashMap<String, CommandOrAlias>) -> HashMap<&String, &I pub fn with_embeds(_: &mut Context, msg: &Message, groups: HashMap<String, Arc<CommandGroup>>, - args: &[String]) + args: Args) -> Result<(), String> { if !args.is_empty() { - let name = args.join(" "); + let name = args.full(); for (group_name, group) in groups { let mut found: Option<(&String, &InternalCommand)> = None; @@ -227,10 +227,10 @@ pub fn with_embeds(_: &mut Context, pub fn plain(_: &mut Context, msg: &Message, groups: HashMap<String, Arc<CommandGroup>>, - args: &[String]) + args: Args) -> Result<(), String> { if !args.is_empty() { - let name = args.join(" "); + let name = args.full(); for (group_name, group) in groups { let mut found: Option<(&String, &Command)> = None; diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs index f9c0e11..382a268 100644 --- a/src/framework/standard/mod.rs +++ b/src/framework/standard/mod.rs @@ -6,6 +6,7 @@ mod configuration; mod create_command; mod create_group; mod buckets; +mod args; pub(crate) use self::buckets::{Bucket, Ratelimit}; pub use self::command::{Command, CommandGroup, CommandType}; @@ -13,6 +14,7 @@ pub use self::command::CommandOrAlias; pub use self::configuration::Configuration; pub use self::create_command::CreateCommand; pub use self::create_group::CreateGroup; +pub use self::args::{Args, Error as ArgError}; use self::command::{AfterHook, BeforeHook}; use std::collections::HashMap; @@ -22,11 +24,7 @@ use client::Context; use super::Framework; use model::{ChannelId, GuildId, Message, UserId}; use model::permissions::Permissions; -use utils; use tokio_core::reactor::Handle; -use itertools::Itertools; -use regex::Regex; -use regex::escape; #[cfg(feature = "cache")] use client::CACHE; @@ -54,7 +52,9 @@ use model::Channel; /// them, sending the product as a reply: /// /// ```rust,ignore -/// command!(multiply(_context, message, _args, first: f64, second: f64) { +/// command!(multiply(_context, message, args) { +/// let first = args.single::<i32>().unwrap(); +/// let second = args.single::<i32>().unwrap(); /// let product = first * second; /// /// if let Err(why) = message.reply(&product.to_string()) { @@ -70,8 +70,7 @@ macro_rules! command { #[allow(unreachable_code, unused_mut)] pub fn $fname(mut $c: &mut $crate::client::Context, _: &$crate::model::Message, - _: Vec<String>, - _: String) + _: Args) -> ::std::result::Result<(), String> { $b @@ -82,8 +81,7 @@ macro_rules! command { #[allow(unreachable_code, unused_mut)] pub fn $fname(mut $c: &mut $crate::client::Context, $m: &$crate::model::Message, - _: Vec<String>, - _: String) + _: Args) -> ::std::result::Result<(), String> { $b @@ -94,71 +92,13 @@ macro_rules! command { #[allow(unreachable_code, unused_mut)] pub fn $fname(mut $c: &mut $crate::client::Context, $m: &$crate::model::Message, - $a: Vec<String>, - _: String) + $a: Args) -> ::std::result::Result<(), String> { $b Ok(()) } }; - ($fname:ident($c:ident, $m:ident, @$a:ident) $b:block) => { - #[allow(unreachable_code, unused_mut)] - pub fn $fname(mut $c: &mut $crate::client::Context, - $m: &$crate::model::Message, - _: Vec<String>, - $a: String) - -> ::std::result::Result<(), String> { - $b - - Ok(()) - } - }; - ($fname:ident($c:ident, $m:ident, $a:ident, @$f:ident) $b:block) => { - #[allow(unreachable_code, unused_mut)] - pub fn $fname(mut $c: &mut $crate::client::Context, - $m: &$crate::model::Message, - $a: Vec<String>, - $f: String) - -> ::std::result::Result<(), String> { - $b - - Ok(()) - } - }; - ($fname:ident($c:ident, $m:ident, $a:ident, $($name:ident: $t:ty),*) $b:block) => { - #[allow(unreachable_code, unreachable_patterns, unused_mut)] - pub fn $fname(mut $c: &mut $crate::client::Context, - $m: &$crate::model::Message, - $a: Vec<String>, - _: String) - -> ::std::result::Result<(), String> { - let mut i = $a.iter(); - let mut arg_counter = 0; - - $( - arg_counter += 1; - - let $name = match i.next() { - Some(v) => match v.parse::<$t>() { - Ok(v) => v, - Err(_) => return Err(format!("Failed to parse argument #{} of type {:?}", - arg_counter, - stringify!($t))), - }, - None => return Err(format!("Missing argument #{} of type {:?}", - arg_counter, - stringify!($t))), - }; - )* - - drop(i); - - $b - - Ok(()) - } - }; } /// A enum representing all possible fail conditions under which a command won't @@ -494,7 +434,7 @@ impl StandardFramework { mut context: &mut Context, message: &Message, command: &Arc<Command>, - args: &[String], + args: &mut Args, to_check: &str, built: &str) -> Option<DispatchError> { @@ -637,7 +577,7 @@ impl StandardFramework { /// # } /// ``` pub fn on<F, S>(mut self, command_name: S, f: F) -> Self - where F: Fn(&mut Context, &Message, Vec<String>, String) -> Result<(), String> + 'static, + where F: Fn(&mut Context, &Message, Args) -> Result<(), String> + 'static, S: Into<String> { { let ungrouped = self.groups.entry("Ungrouped".to_owned()).or_insert_with( @@ -940,40 +880,23 @@ impl Framework for StandardFramework { let after = self.after.clone(); let groups = self.groups.clone(); - let (args, content) = { + let mut args = { let mut content = message.content[position..].trim(); - content = content[command_length..].trim(); - - if command.use_quotes { - (utils::parse_quotes(content), content.to_string()) - } else { - let delimiters = &self.configuration.delimiters; - let regular_expression = delimiters - .iter() - .map(|delimiter| escape(delimiter)) - .join("|"); - - let regex = Regex::new(®ular_expression).unwrap(); - - ( - regex - .split(content) - .filter_map(|p| if p.is_empty() { - None - } else { - Some(p.to_string()) - }) - .collect::<Vec<_>>(), - content.to_string(), - ) - } + content = content[command_length..].trim(); + + let delimiter = self.configuration.delimiters + .iter() + .find(|&d| content.contains(d)) + .map_or(" ", |s| s.as_str()); + + Args::new(&content, delimiter) }; if let Some(error) = self.should_fail( &mut context, &message, &command, - &args, + &mut args, &to_check, &built, ) { @@ -997,10 +920,10 @@ impl Framework for StandardFramework { Ok(()) }, CommandType::Basic(ref x) => { - (x)(&mut context, &message, args, content) + (x)(&mut context, &message, args) }, CommandType::WithCommands(ref x) => { - (x)(&mut context, &message, groups, &args) + (x)(&mut context, &message, groups, args) }, }; |