aboutsummaryrefslogtreecommitdiff
path: root/src/framework
diff options
context:
space:
mode:
authoracdenisSK <[email protected]>2017-10-14 22:41:25 +0200
committeracdenisSK <[email protected]>2017-10-14 22:41:25 +0200
commitcae014758a1d1e926a71679f02e32601c57f8d52 (patch)
tree39270dbc2df916a91c3c4272600fd082a2604516 /src/framework
parentSwitch to parking_lot::{Mutex, RwLock} (diff)
parentRelease v0.4.1 (diff)
downloadserenity-cae014758a1d1e926a71679f02e32601c57f8d52.tar.xz
serenity-cae014758a1d1e926a71679f02e32601c57f8d52.zip
Update to account for changes made in 0.4.1
Diffstat (limited to 'src/framework')
-rw-r--r--src/framework/standard/args.rs49
-rw-r--r--src/framework/standard/help_commands.rs143
-rw-r--r--src/framework/standard/mod.rs16
3 files changed, 125 insertions, 83 deletions
diff --git a/src/framework/standard/args.rs b/src/framework/standard/args.rs
index 30264b3..f59908a 100644
--- a/src/framework/standard/args.rs
+++ b/src/framework/standard/args.rs
@@ -53,6 +53,10 @@ impl<E: StdError> fmt::Display for Error<E> {
type Result<T, E> = ::std::result::Result<T, Error<E>>;
+/// A utility struct for handling arguments of a command.
+///
+/// General functionality is done via removing an item, parsing it, then returning it; this however
+/// can be mitigated with the `*_n` methods, which just parse and return.
#[derive(Clone, Debug)]
pub struct Args {
delimiter: String,
@@ -116,10 +120,7 @@ impl Args {
let mut vec = Vec::with_capacity(i as usize);
for _ in 0..i {
- vec.push(match self.delimiter_split.shift() {
- Some(x) => x,
- None => return None,
- });
+ vec.push(try_opt!(self.delimiter_split.shift()));
}
Some(vec)
@@ -161,16 +162,14 @@ impl Args {
}
/// Empty outs the internal vector while parsing (if necessary) and returning them
- pub fn list<T: FromStr>(self) -> Result<Vec<T>, T::Err>
+ pub fn list<T: FromStr>(mut self) -> Result<Vec<T>, T::Err>
where T::Err: StdError {
- if self.delimiter_split.is_empty() {
- return Err(Error::Eos);
- }
+ Iter::<T>::new(&mut self).collect()
+ }
- self.delimiter_split
- .into_iter()
- .map(|s| s.parse::<T>().map_err(Error::Parse))
- .collect()
+ /// Provides an iterator of items: (`T: FromStr`) `Result<T, T::Err>`.
+ pub fn iter<T: FromStr>(&mut self) -> Iter<T> where T::Err: StdError {
+ Iter::new(self)
}
/// This method is just `internal_vector.join(delimiter)`
@@ -221,3 +220,29 @@ impl ::std::ops::Deref for Args {
fn deref(&self) -> &Self::Target { &self.delimiter_split }
}
+
+use std::marker::PhantomData;
+
+/// Provides `list`'s functionality, but as an iterator.
+pub struct Iter<'a, T: FromStr> where T::Err: StdError {
+ args: &'a mut Args,
+ _marker: PhantomData<T>,
+}
+
+impl<'a, T: FromStr> Iter<'a, T> where T::Err: StdError {
+ fn new(args: &'a mut Args) -> Self {
+ Iter { args, _marker: PhantomData }
+ }
+}
+
+impl<'a, T: FromStr> Iterator for Iter<'a, T> where T::Err: StdError {
+ type Item = Result<T, T::Err>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.args.is_empty() {
+ None
+ } else {
+ Some(self.args.single::<T>())
+ }
+ }
+}
diff --git a/src/framework/standard/help_commands.rs b/src/framework/standard/help_commands.rs
index dbf25a9..ce90e74 100644
--- a/src/framework/standard/help_commands.rs
+++ b/src/framework/standard/help_commands.rs
@@ -29,7 +29,7 @@ use std::fmt::Write;
use super::command::InternalCommand;
use super::{Args, Command, CommandGroup, CommandOrAlias, CommandError};
use client::Context;
-use model::{ChannelId, Guild, Member, Message};
+use model::{ChannelId, Message};
use utils::Colour;
use framework::standard::{has_correct_roles, has_correct_permissions};
@@ -51,14 +51,25 @@ fn remove_aliases(cmds: &HashMap<String, CommandOrAlias>) -> HashMap<&String, &I
result
}
-/// Checks whether a user is member of required roles
+/// Checks whether a user is member of required roles
/// and given the required permissions.
-fn has_all_requirements(cmd: &Command, guild: &Guild, member: &Member, msg: &Message) -> bool {
- if cmd.allowed_roles.is_empty() {
- has_correct_permissions(cmd, msg)
- } else {
- has_correct_roles(cmd, guild, member) && has_correct_permissions(cmd, msg)
+pub fn has_all_requirements(cmd: &Command, msg: &Message) -> bool {
+ if let Some(guild) = msg.guild() {
+ let guild = guild.read();
+
+ if let Some(member) = guild.members.get(&msg.author.id) {
+
+ if let Ok(permissions) = member.permissions() {
+
+ if cmd.allowed_roles.is_empty() {
+ return permissions.administrator() || has_correct_permissions(&cmd, &msg);
+ } else {
+ return permissions.administrator() || (has_correct_roles(&cmd, &guild, &member) && has_correct_permissions(cmd, msg));
+ }
+ }
+ }
}
+ false
}
/// Posts an embed showing each individual command group and its commands.
@@ -100,26 +111,31 @@ pub fn with_embeds(_: &mut Context,
if name == with_prefix || name == *command_name {
match *command {
CommandOrAlias::Command(ref cmd) => {
- if !cmd.allowed_roles.is_empty() {
- if let Some(guild) = msg.guild() {
- let guild = guild.read();
-
- if let Some(member) = guild.members.get(&msg.author.id) {
- if let Ok(permissions) = member.permissions() {
- if !permissions.administrator() &&
- !has_all_requirements(cmd, &guild, member, &msg) {
- break;
- }
- }
- }
- }
+ if has_all_requirements(&cmd, &msg) {
+ found = Some((command_name, cmd));
}
- found = Some((command_name, cmd));
+ else {
+ break;
+ }
},
CommandOrAlias::Alias(ref name) => {
- error_embed(&msg.channel_id, &format!("Did you mean \"{}\"?", name));
+ let actual_command = group.commands.get(name).unwrap();
- return Ok(());
+ match *actual_command {
+ CommandOrAlias::Command(ref cmd) => {
+ if has_all_requirements(&cmd, &msg) {
+ found = Some((name, cmd));
+ }
+ else {
+ break;
+ }
+ },
+
+ CommandOrAlias::Alias(ref name) => {
+ let _ = msg.channel_id.say(&format!("Did you mean {:?}?", name));
+ return Ok(());
+ },
+ }
},
}
}
@@ -135,6 +151,7 @@ pub fn with_embeds(_: &mut Context,
let _ = msg.channel_id.send_message(|m| {
m.embed(|e| {
let mut embed = e.colour(Colour::rosewater()).title(command_name);
+
if let Some(ref desc) = command.desc {
embed = embed.description(desc);
}
@@ -157,6 +174,11 @@ pub fn with_embeds(_: &mut Context,
embed = embed.field(|f| f.name("Group").value(&group_name));
}
+ if !command.aliases.is_empty() {
+ let aliases = command.aliases.join(", ");
+ embed = embed.field(|f| f.name("Aliases").value(&aliases));
+ }
+
let available = if command.dm_only {
"Only in DM"
} else if command.guild_only {
@@ -209,22 +231,14 @@ pub fn with_embeds(_: &mut Context,
let cmd = &commands[name];
if cmd.help_available {
- if let Some(guild) = msg.guild() {
- let guild = guild.read();
-
- if let Some(member) = guild.members.get(&msg.author.id) {
- if let Ok(permissions) = member.permissions() {
- if cmd.help_available &&
- (has_all_requirements(cmd, &guild, member, &msg) ||
- permissions.administrator()) {
- let _ = write!(desc, "`{}`\n", name);
- has_commands = true;
- }
- }
- }
+
+ if cmd.help_available && has_all_requirements(&cmd, &msg) {
+ let _ = write!(desc, "`{}`\n", name);
+ has_commands = true;
}
}
}
+
if has_commands {
e = e.field(|f| f.name(group_name).value(&desc));
}
@@ -275,25 +289,31 @@ pub fn plain(_: &mut Context,
if name == with_prefix || name == *command_name {
match *command {
CommandOrAlias::Command(ref cmd) => {
- if !cmd.allowed_roles.is_empty() {
- if let Some(guild) = msg.guild() {
- let guild = guild.read();
-
- if let Some(member) = guild.members.get(&msg.author.id) {
- if let Ok(permissions) = member.permissions() {
- if !permissions.administrator() &&
- !has_all_requirements(cmd, &guild, member, &msg) {
- break;
- }
- }
- }
- }
+ if has_all_requirements(&cmd, &msg) {
+ found = Some((command_name, cmd));
+ }
+ else {
+ break;
}
- found = Some((command_name, cmd));
},
CommandOrAlias::Alias(ref name) => {
- let _ = msg.channel_id.say(&format!("Did you mean {:?}?", name));
- return Ok(());
+ let actual_command = group.commands.get(name).unwrap();
+
+ match *actual_command {
+ CommandOrAlias::Command(ref cmd) => {
+ if has_all_requirements(&cmd, &msg) {
+ found = Some((name, cmd));
+ }
+ else {
+ break;
+ }
+ },
+
+ CommandOrAlias::Alias(ref name) => {
+ let _ = msg.channel_id.say(&format!("Did you mean {:?}?", name));
+ return Ok(());
+ },
+ }
},
}
}
@@ -307,6 +327,11 @@ pub fn plain(_: &mut Context,
let mut result = format!("**{}**\n", command_name);
+ if !command.aliases.is_empty() {
+ let aliases = command.aliases.join("`, `");
+ let _ = write!(result, "**Aliases:** `{}`\n", aliases);
+ }
+
if let Some(ref desc) = command.desc {
let _ = write!(result, "**Description:** {}\n", desc);
}
@@ -364,17 +389,9 @@ pub fn plain(_: &mut Context,
for name in command_names {
let cmd = &commands[name];
- if let Some(guild) = msg.guild() {
- let guild = guild.read();
-
- if let Some(member) = guild.members.get(&msg.author.id) {
- if let Ok(permissions) = member.permissions() {
- if cmd.help_available &&
- (permissions.administrator() || has_all_requirements(cmd, &guild, member, &msg)) {
- let _ = write!(group_help, "`{}` ", name);
- }
- }
- }
+
+ if cmd.help_available && has_all_requirements(&cmd, &msg) {
+ let _ = write!(group_help, "`{}` ", name);
}
}
diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs
index c3f0d70..6504c6a 100644
--- a/src/framework/standard/mod.rs
+++ b/src/framework/standard/mod.rs
@@ -417,6 +417,7 @@ impl StandardFramework {
}
#[allow(too_many_arguments)]
+ #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
fn should_fail(&mut self,
mut context: &mut Context,
message: &Message,
@@ -514,10 +515,9 @@ impl StandardFramework {
if let Some(member) = guild.members.get(&message.author.id) {
if let Ok(permissions) = member.permissions() {
- if !permissions.administrator() {
- if !has_correct_roles(&command, &guild, &member) {
- return Some(DispatchError::LackingRole);
- }
+ if !permissions.administrator()
+ && !has_correct_roles(command, &guild, member) {
+ return Some(DispatchError::LackingRole);
}
}
}
@@ -532,7 +532,7 @@ impl StandardFramework {
if all_passed {
None
} else {
- Some(DispatchError::CheckFailed(command.clone()))
+ Some(DispatchError::CheckFailed(Arc::clone(command)))
}
}
}
@@ -875,7 +875,7 @@ impl Framework for StandardFramework {
if let Some(&CommandOrAlias::Command(ref command)) =
group.commands.get(&to_check) {
let before = self.before.clone();
- let command = command.clone();
+ let command = Arc::clone(command);
let after = self.after.clone();
let groups = self.groups.clone();
@@ -935,7 +935,7 @@ impl Framework for StandardFramework {
}
#[cfg(feature = "cache")]
-pub(crate) fn has_correct_permissions(command: &Command, message: &Message) -> bool {
+pub fn has_correct_permissions(command: &Command, message: &Message) -> bool {
if !command.required_permissions.is_empty() {
if let Some(guild) = message.guild() {
let perms = guild
@@ -949,7 +949,7 @@ pub(crate) fn has_correct_permissions(command: &Command, message: &Message) -> b
}
#[cfg(feature = "cache")]
-pub(crate) fn has_correct_roles(cmd: &Command, guild: &Guild, member: &Member) -> bool {
+pub fn has_correct_roles(cmd: &Command, guild: &Guild, member: &Member) -> bool {
cmd.allowed_roles
.iter()
.flat_map(|r| guild.role_by_name(r))