aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/06_command_framework.rs2
-rw-r--r--src/ext/framework/command.rs55
-rw-r--r--src/ext/framework/mod.rs62
3 files changed, 72 insertions, 47 deletions
diff --git a/examples/06_command_framework.rs b/examples/06_command_framework.rs
index cb838fd..b93b952 100644
--- a/examples/06_command_framework.rs
+++ b/examples/06_command_framework.rs
@@ -21,9 +21,9 @@ fn main() {
// Commands are equivilant to:
// "~about"
- // "~ping"
// "~emoji cat"
// "~emoji dog"
+ // "~ping"
// "~some complex command"
client.with_framework(|f| f
.configure(|c| c
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
+}
diff --git a/src/ext/framework/mod.rs b/src/ext/framework/mod.rs
index 1949e24..80844c3 100644
--- a/src/ext/framework/mod.rs
+++ b/src/ext/framework/mod.rs
@@ -11,6 +11,13 @@ use std::thread;
use ::client::Context;
use ::model::Message;
+#[derive(Clone, Copy, Debug)]
+pub enum CommandType {
+ Mention,
+ None,
+ Prefix,
+}
+
#[allow(type_complexity)]
#[derive(Default)]
pub struct Framework {
@@ -31,54 +38,17 @@ impl Framework {
#[doc(hidden)]
pub fn dispatch(&mut self, context: Context, message: Message) {
- // Determine the point at which the prefix ends, and the command starts.
- let positions = if let Some(ref prefix) = self.configuration.prefix {
- let pos = if let Some(mention_ends) = self.find_mention_end(&message.content) {
- mention_ends
- } else if !message.content.starts_with(prefix) {
- return;
- } else {
- prefix.len()
- };
-
- let mut positions = vec![pos];
-
- if self.configuration.allow_whitespace {
- positions.push(pos - 1);
- }
-
- positions
- } else if self.configuration.on_mention.is_some() {
- match self.find_mention_end(&message.content) {
- Some(mention_end) => {
- let mut positions = vec![mention_end];
-
- if self.configuration.allow_whitespace {
- positions.push(mention_end - 1);
- }
+ let res = command::positions(&message.content, &self.configuration);
- positions
- },
- None => return,
- }
- } else {
- vec![0]
+ let (positions, kind) = match res {
+ Some((positions, kind)) => (positions, kind),
+ None => return,
};
- // Ensure that the message length is at least longer than the prefix
+ // Ensure that the message length is at least longer than a prefix
// length. There's no point in checking further ahead if there's nothing
- // to check.
- let mut less_than = true;
-
- for position in &positions {
- if message.content.len() > *position {
- less_than = false;
-
- break;
- }
- }
-
- if less_than {
+ // _to_ check.
+ if positions.iter().all(|p| message.content.len() <= *p) {
return;
}
@@ -86,7 +56,7 @@ impl Framework {
let mut built = String::new();
for i in 0..self.configuration.depth {
- if i > 0 {
+ if i != 0 {
built.push(' ');
}
@@ -113,7 +83,7 @@ impl Framework {
let command = command.clone();
thread::spawn(move || {
- let args = message.content[built.len() + 1..]
+ let args = message.content[position + built.len()..]
.split_whitespace()
.map(|arg| arg.to_owned())
.collect::<Vec<String>>();