diff options
| author | acdenisSK <[email protected]> | 2017-10-14 22:41:25 +0200 |
|---|---|---|
| committer | acdenisSK <[email protected]> | 2017-10-14 22:41:25 +0200 |
| commit | cae014758a1d1e926a71679f02e32601c57f8d52 (patch) | |
| tree | 39270dbc2df916a91c3c4272600fd082a2604516 /src/framework | |
| parent | Switch to parking_lot::{Mutex, RwLock} (diff) | |
| parent | Release v0.4.1 (diff) | |
| download | serenity-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.rs | 49 | ||||
| -rw-r--r-- | src/framework/standard/help_commands.rs | 143 | ||||
| -rw-r--r-- | src/framework/standard/mod.rs | 16 |
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)) |