diff options
| author | Austin Hellyer <[email protected]> | 2016-11-08 14:56:37 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-11-08 14:56:37 -0800 |
| commit | 489dab2f34588153079ab1373f988835170c9b9a (patch) | |
| tree | 3f64350c97f294ffa31c8e245ac6507871585d15 /src/ext/framework/command.rs | |
| parent | Add Manage Webhooks to permissions 2FA list (diff) | |
| download | serenity-489dab2f34588153079ab1373f988835170c9b9a.tar.xz serenity-489dab2f34588153079ab1373f988835170c9b9a.zip | |
Framework: fix command arg positioning
The command system assumed that prefixes were only one character long,
so count the total length of the prefix. In addition, the
`allow_whitespace` configuration added some difficulty in deciding where
to count as the initial position to start splitting for arguments.
Instead of fixing that, rewrite the framework to make these types of
changes easier in the future.
Diffstat (limited to 'src/ext/framework/command.rs')
| -rw-r--r-- | src/ext/framework/command.rs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/ext/framework/command.rs b/src/ext/framework/command.rs index 43d3c9a..6a9a713 100644 --- a/src/ext/framework/command.rs +++ b/src/ext/framework/command.rs @@ -1,7 +1,62 @@ use std::sync::Arc; +use super::{CommandType, Configuration}; use ::client::Context; use ::model::Message; pub type Command = Fn(Context, Message, Vec<String>) + Send + Sync; #[doc(hidden)] pub type InternalCommand = Arc<Command>; + +pub fn positions(content: &str, conf: &Configuration) + -> Option<(Vec<usize>, CommandType)> { + if let Some(ref prefix) = conf.prefix { + // Find out if they were mentioned. If not, determine if the prefix + // was used. If not, return None. + let (mut positions, kind) = if let Some(mention_end) = find_mention_end(content, conf) { + (vec![mention_end], CommandType::Mention) + } else if content.starts_with(prefix) { + (vec![prefix.len()], CommandType::Prefix) + } else { + return None; + }; + + if conf.allow_whitespace { + let pos = *unsafe { + positions.get_unchecked(0) + }; + + positions.insert(0, pos + 1); + } + + Some((positions, kind)) + } else if conf.on_mention.is_some() { + match find_mention_end(content, conf) { + Some(mention_end) => { + let mut positions = vec![mention_end]; + + if conf.allow_whitespace { + positions.insert(0, mention_end + 1); + } + + Some((positions, CommandType::Mention)) + }, + None => None, + } + } else { + None + } +} + +fn find_mention_end(content: &str, conf: &Configuration) -> Option<usize> { + if let Some(ref mentions) = conf.on_mention { + for mention in mentions { + if !content.starts_with(&mention[..]) { + continue; + } + + return Some(mention.len()); + } + } + + None +} |