aboutsummaryrefslogtreecommitdiff
path: root/src/framework
diff options
context:
space:
mode:
authoracdenisSK <[email protected]>2017-08-20 23:02:38 +0200
committeracdenisSK <[email protected]>2017-08-20 23:05:34 +0200
commit45d72eff173d87b1353d8b5d001775cc49129dab (patch)
tree5ecfdf54bbaeb597bd557c0307ddfd6392b7860e /src/framework
parentUse wildcard (diff)
downloadserenity-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.rs13
-rw-r--r--src/framework/standard/create_command.rs33
-rw-r--r--src/framework/standard/create_group.rs3
-rw-r--r--src/framework/standard/help_commands.rs10
-rw-r--r--src/framework/standard/mod.rs121
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(&regular_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)
},
};