diff options
| author | Illia <[email protected]> | 2016-12-10 22:25:55 +0200 |
|---|---|---|
| committer | zeyla <[email protected]> | 2016-12-10 12:25:55 -0800 |
| commit | e44838f4339b90817b5eba5df16230b02487f0cc (patch) | |
| tree | 8513ab3d9d3f9c8826f85630524cca1e4a7e188d /src | |
| parent | Fix no-cache+method conditional compiles (diff) | |
| download | serenity-e44838f4339b90817b5eba5df16230b02487f0cc.tar.xz serenity-e44838f4339b90817b5eba5df16230b02487f0cc.zip | |
More config for CreateCommand, add various methods
Adds multiple configurations to the command builder, and adds methods
to various structs.
Context::get_current_user is a shortcut to retrieve the current user
from the cache.
Message::get_member retrieves the member object of the message, if sent
in a guild. Message::is_private checks if the message was sent in a
Group or PrivateChannel.
User::member retrieves the user's member object in a guild by Id;
Adds 6 configurations to the command builder:
- dm_only: whether the command can only be used in direct messages;
- guild_only: whether the command can only be used in guilds;
- help_available: whether the command should be displayed in the help
list;
- max_args: specify the maximum number of arguments a command must be
given;
- min_args: specify the minimum number of arguments a command must be
given;
- required_permissions: the permissions a member must have to be able
to use the command;
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/context.rs | 11 | ||||
| -rw-r--r-- | src/client/dispatch.rs | 2 | ||||
| -rw-r--r-- | src/client/event_store.rs | 54 | ||||
| -rw-r--r-- | src/client/gateway/prep.rs | 4 | ||||
| -rw-r--r-- | src/client/gateway/shard.rs | 2 | ||||
| -rw-r--r-- | src/client/mod.rs | 12 | ||||
| -rw-r--r-- | src/error.rs | 14 | ||||
| -rw-r--r-- | src/ext/framework/command.rs | 13 | ||||
| -rw-r--r-- | src/ext/framework/configuration.rs | 24 | ||||
| -rw-r--r-- | src/ext/framework/create_command.rs | 49 | ||||
| -rw-r--r-- | src/ext/framework/mod.rs | 73 | ||||
| -rw-r--r-- | src/ext/mod.rs | 6 | ||||
| -rw-r--r-- | src/internal/mod.rs | 4 | ||||
| -rw-r--r-- | src/model/channel.rs | 117 | ||||
| -rw-r--r-- | src/model/guild.rs | 68 | ||||
| -rw-r--r-- | src/model/id.rs | 16 | ||||
| -rw-r--r-- | src/model/invite.rs | 2 | ||||
| -rw-r--r-- | src/model/mod.rs | 8 | ||||
| -rw-r--r-- | src/model/user.rs | 23 | ||||
| -rw-r--r-- | src/model/utils.rs | 2 | ||||
| -rw-r--r-- | src/utils/macros.rs | 48 |
21 files changed, 376 insertions, 176 deletions
diff --git a/src/client/context.rs b/src/client/context.rs index eb7246b..e646ec6 100644 --- a/src/client/context.rs +++ b/src/client/context.rs @@ -22,7 +22,7 @@ use ::internal::prelude::*; use ::model::*; use ::utils; -#[cfg(feature = "cache")] +#[cfg(feature="cache")] use super::CACHE; /// The context is a general utility struct provided on event dispatches, which @@ -1077,6 +1077,15 @@ impl Context { Ok(channels) } + /// Gets information about the current user. + /// + /// Note this is shorthand for retrieving the current user through the + /// cache, and will perform a clone. + #[cfg(all(feature = "cache", feature = "methods"))] + pub fn get_current_user(&self) -> CurrentUser { + CACHE.read().unwrap().user.clone() + } + /// Gets an [`Guild`]'s emoji by Id. /// /// Requires the [Manage Emojis] permission. diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 7b0439d..5f61ea9 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -11,7 +11,7 @@ use ::model::{ChannelId, Message}; #[cfg(feature="framework")] use ::ext::framework::Framework; -#[cfg(feature = "cache")] +#[cfg(feature="cache")] use super::CACHE; macro_rules! handler { diff --git a/src/client/event_store.rs b/src/client/event_store.rs index e2ddf94..7cc7e81 100644 --- a/src/client/event_store.rs +++ b/src/client/event_store.rs @@ -14,7 +14,7 @@ use ::model::event::{ }; use ::model::*; -#[cfg(not(feature = "cache"))] +#[cfg(not(feature="cache"))] use ::model::event::{ CallUpdateEvent, GuildMemberUpdateEvent, @@ -43,13 +43,13 @@ use ::model::event::{ #[derive(Default)] pub struct EventStore { pub on_call_create: Option<Arc<Fn(Context, Call) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_call_delete: Option<Arc<Fn(Context, ChannelId, Option<Call>) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_call_delete: Option<Arc<Fn(Context, ChannelId) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_call_update: Option<Arc<Fn(Context, Option<Call>, Option<Call>) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_call_update: Option<Arc<Fn(Context, CallUpdateEvent) + Send + Sync + 'static>>, pub on_channel_create: Option<Arc<Fn(Context, Channel) + Send + Sync + 'static>>, pub on_channel_delete: Option<Arc<Fn(Context, Channel) + Send + Sync + 'static>>, @@ -57,45 +57,45 @@ pub struct EventStore { pub on_channel_pins_update: Option<Arc<Fn(Context, ChannelPinsUpdateEvent) + Send + Sync + 'static>>, pub on_channel_recipient_addition: Option<Arc<Fn(Context, ChannelId, User) + Send + Sync + 'static>>, pub on_channel_recipient_removal: Option<Arc<Fn(Context, ChannelId, User) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_channel_update: Option<Arc<Fn(Context, Option<Channel>, Channel) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_channel_update: Option<Arc<Fn(Context, Channel) + Send + Sync + 'static>>, pub on_friend_suggestion_create: Option<Arc<Fn(Context, User, Vec<SuggestionReason>) + Send + Sync + 'static>>, pub on_friend_suggestion_delete: Option<Arc<Fn(Context, UserId) + Send + Sync + 'static>>, pub on_guild_ban_addition: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>, pub on_guild_ban_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>, pub on_guild_create: Option<Arc<Fn(Context, Guild) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_guild_delete: Option<Arc<Fn(Context, PartialGuild, Option<Guild>) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_guild_delete: Option<Arc<Fn(Context, PartialGuild) + Send + Sync + 'static>>, pub on_guild_emojis_update: Option<Arc<Fn(Context, GuildId, HashMap<EmojiId, Emoji>) + Send + Sync + 'static>>, pub on_guild_integrations_update: Option<Arc<Fn(Context, GuildId) + Send + Sync + 'static>>, pub on_guild_member_addition: Option<Arc<Fn(Context, GuildId, Member) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_guild_member_update: Option<Arc<Fn(Context, Option<Member>, Member) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_guild_member_update: Option<Arc<Fn(Context, GuildMemberUpdateEvent) + Send + Sync + 'static>>, pub on_guild_members_chunk: Option<Arc<Fn(Context, GuildId, HashMap<UserId, Member>) + Send + Sync + 'static>>, pub on_guild_role_create: Option<Arc<Fn(Context, GuildId, Role) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Role) + Send + Sync + 'static>>, pub on_guild_sync: Option<Arc<Fn(Context, GuildSyncEvent) + Send + Sync + 'static>>, pub on_guild_unavailable: Option<Arc<Fn(Context, GuildId) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_guild_update: Option<Arc<Fn(Context, Option<Guild>, PartialGuild) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_guild_update: Option<Arc<Fn(Context, PartialGuild) + Send + Sync + 'static>>, pub on_message: Option<Arc<Fn(Context, Message) + Send + Sync + 'static>>, pub on_message_ack: Option<Arc<Fn(Context, ChannelId, Option<MessageId>) + Send + Sync + 'static>>, @@ -105,9 +105,9 @@ pub struct EventStore { pub on_reaction_remove: Option<Arc<Fn(Context, Reaction) + Send + Sync + 'static>>, pub on_reaction_remove_all: Option<Arc<Fn(Context, ChannelId, MessageId) + Send + Sync + 'static>>, pub on_message_update: Option<Arc<Fn(Context, MessageUpdateEvent) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_note_update: Option<Arc<Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_note_update: Option<Arc<Fn(Context, UserId, String) + Send + Sync + 'static>>, pub on_presence_replace: Option<Arc<Fn(Context, Vec<Presence>) + Send + Sync + 'static>>, pub on_presence_update: Option<Arc<Fn(Context, PresenceUpdateEvent) + Send + Sync + 'static>>, @@ -117,17 +117,17 @@ pub struct EventStore { pub on_resume: Option<Arc<Fn(Context, ResumedEvent) + Send + Sync + 'static>>, pub on_typing_start: Option<Arc<Fn(Context, TypingStartEvent) + Send + Sync + 'static>>, pub on_unknown: Option<Arc<Fn(Context, String, BTreeMap<String, Value>) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_user_guild_settings_update: Option<Arc<Fn(Context, Option<UserGuildSettings>, UserGuildSettings) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_user_guild_settings_update: Option<Arc<Fn(Context, UserGuildSettings) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_user_update: Option<Arc<Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_user_update: Option<Arc<Fn(Context, CurrentUser) + Send + Sync + 'static>>, - #[cfg(feature = "cache")] + #[cfg(feature="cache")] pub on_user_settings_update: Option<Arc<Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static>>, - #[cfg(not(feature = "cache"))] + #[cfg(not(feature="cache"))] pub on_user_settings_update: Option<Arc<Fn(Context, UserSettingsUpdateEvent) + Send + Sync + 'static>>, pub on_voice_server_update: Option<Arc<Fn(Context, VoiceServerUpdateEvent) + Send + Sync + 'static>>, pub on_voice_state_update: Option<Arc<Fn(Context, Option<GuildId>, VoiceState) + Send + Sync + 'static>>, diff --git a/src/client/gateway/prep.rs b/src/client/gateway/prep.rs index 3844a8d..4602ea6 100644 --- a/src/client/gateway/prep.rs +++ b/src/client/gateway/prep.rs @@ -80,12 +80,12 @@ pub fn identify(token: &str, shard_info: Option<[u8; 2]>) -> Value { .build() } -#[cfg(not(feature = "debug"))] +#[cfg(not(feature="debug"))] pub fn identify_compression(object: ObjectBuilder) -> ObjectBuilder { object.insert("compression", true) } -#[cfg(feature = "debug")] +#[cfg(feature="debug")] pub fn identify_compression(object: ObjectBuilder) -> ObjectBuilder { object.insert("compression", false) } diff --git a/src/client/gateway/shard.rs b/src/client/gateway/shard.rs index 232d2c3..c026f0c 100644 --- a/src/client/gateway/shard.rs +++ b/src/client/gateway/shard.rs @@ -69,7 +69,7 @@ pub struct Shard { ws_url: String, /// The voice connections that this Shard is responsible for. The Shard will /// update the voice connections' states. - #[cfg(feature = "voice")] + #[cfg(feature="voice")] pub manager: VoiceManager, } diff --git a/src/client/mod.rs b/src/client/mod.rs index 843bbfe..c9a9c65 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -61,20 +61,20 @@ use ::model::event::{ }; use ::model::*; -#[cfg(feature = "framework")] +#[cfg(feature="framework")] use ::ext::framework::Framework; -#[cfg(feature = "cache")] +#[cfg(feature="cache")] use ::ext::cache::Cache; -#[cfg(not(feature = "cache"))] +#[cfg(not(feature="cache"))] use ::model::event::{ CallUpdateEvent, GuildMemberUpdateEvent, UserSettingsUpdateEvent, }; -#[cfg(feature = "cache")] +#[cfg(feature="cache")] lazy_static! { /// A mutable and lazily-initialized static binding. It can be accessed /// across any function and in any context. @@ -841,7 +841,7 @@ impl Client { } } -#[cfg(feature = "cache")] +#[cfg(feature="cache")] impl Client { /// Attaches a handler for when a [`CallDelete`] is received. /// @@ -1003,7 +1003,7 @@ impl Client { } } -#[cfg(not(feature = "cache"))] +#[cfg(not(feature="cache"))] impl Client { /// Attaches a handler for when a [`CallDelete`] is received. /// diff --git a/src/error.rs b/src/error.rs index 10f8d36..41bda57 100644 --- a/src/error.rs +++ b/src/error.rs @@ -7,7 +7,7 @@ use std::fmt::{self, Display, Error as FormatError}; use websocket::result::WebSocketError; use ::client::gateway::GatewayError; use ::client::ClientError; -#[cfg(feature = "voice")] +#[cfg(feature="voice")] use opus::Error as OpusError; #[cfg(feature="voice")] use ::ext::voice::VoiceError; @@ -66,12 +66,12 @@ pub enum Error { /// An error from the `rust-websocket` crate. WebSocket(WebSocketError), /// An error from the `opus` crate. - #[cfg(feature = "voice")] + #[cfg(feature="voice")] Opus(OpusError), /// Indicating an error within the [voice module]. /// /// [voice module]: ext/voice/index.html - #[cfg(feature = "voice")] + #[cfg(feature="voice")] Voice(VoiceError), } @@ -99,7 +99,7 @@ impl From<JsonError> for Error { } } -#[cfg(feature = "voice")] +#[cfg(feature="voice")] impl From<OpusError> for Error { fn from(e: OpusError) -> Error { Error::Opus(e) @@ -119,7 +119,7 @@ impl Display for Error { Error::Io(ref inner) => inner.fmt(f), Error::Json(ref inner) => inner.fmt(f), Error::WebSocket(ref inner) => inner.fmt(f), - #[cfg(feature = "voice")] + #[cfg(feature="voice")] Error::Opus(ref inner) => inner.fmt(f), _ => f.write_str(self.description()), } @@ -138,9 +138,9 @@ impl StdError for Error { Error::Json(ref inner) => inner.description(), Error::Url(ref inner) => inner, Error::WebSocket(ref inner) => inner.description(), - #[cfg(feature = "voice")] + #[cfg(feature="voice")] Error::Opus(ref inner) => inner.description(), - #[cfg(feature = "voice")] + #[cfg(feature="voice")] Error::Voice(_) => "Voice error", } } diff --git a/src/ext/framework/command.rs b/src/ext/framework/command.rs index b7d5bb8..204c90c 100644 --- a/src/ext/framework/command.rs +++ b/src/ext/framework/command.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use super::Configuration; use ::client::Context; use ::model::Message; +use ::model::Permissions; use std::collections::HashMap; pub type Check = Fn(&Context, &Message) -> bool + Send + Sync + 'static; @@ -33,6 +34,18 @@ pub struct Command { 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. + pub max_args: Option<i32>, + /// Permissions required to use this command. + pub required_permissions: Permissions, + /// Whether command should be displayed in help list or not, used by other commands. + pub help_available: bool, + /// Whether command can be used only privately or not. + pub dm_only: bool, + /// Whether command can be used only in guilds or not. + pub guild_only: bool, } pub fn positions(ctx: &Context, content: &str, conf: &Configuration) -> Option<Vec<usize>> { diff --git a/src/ext/framework/configuration.rs b/src/ext/framework/configuration.rs index 9caa48b..e95faea 100644 --- a/src/ext/framework/configuration.rs +++ b/src/ext/framework/configuration.rs @@ -3,6 +3,18 @@ use super::command::PrefixCheck; use ::client::rest; use ::client::Context; +/// Account type used for configuration. +pub enum AccountType { + /// Connected client will only listen to itself. + Selfbot, + /// Connected client will ignore all bot accounts. + Bot, + /// Connected client will listen to everyone. + Any, + #[doc(hidden)] + Automatic +} + /// The configuration to use for a [`Framework`] associated with a [`Client`] /// instance. /// @@ -36,6 +48,8 @@ pub struct Configuration { pub prefixes: Vec<String>, #[doc(hidden)] pub dynamic_prefix: Option<Box<PrefixCheck>>, + #[doc(hidden)] + pub account_type: AccountType } impl Configuration { @@ -136,6 +150,13 @@ impl Configuration { self } + /// Allows you to change what accounts to ignore. + pub fn account_type(mut self, account_type: AccountType) -> Self { + self.account_type = account_type; + + self + } + /// Sets the prefix to respond to. This can either be a single-char or /// multi-char string. pub fn dynamic_prefix<F>(mut self, dynamic_prefix: F) -> Self @@ -159,7 +180,8 @@ impl Default for Configuration { on_mention: None, allow_whitespace: false, prefixes: vec![], - dynamic_prefix: None + dynamic_prefix: None, + account_type: AccountType::Automatic } } } diff --git a/src/ext/framework/create_command.rs b/src/ext/framework/create_command.rs index 824c3dd..6d40592 100644 --- a/src/ext/framework/create_command.rs +++ b/src/ext/framework/create_command.rs @@ -5,6 +5,7 @@ use std::default::Default; use std::sync::Arc; use ::client::Context; use ::model::Message; +use ::model::Permissions; pub struct CreateCommand(pub Command); @@ -54,6 +55,48 @@ impl CreateCommand { self } + /// Whether command should be displayed in help list or not, used by other commands. + pub fn help_available(mut self, help_available: bool) -> Self { + self.0.help_available = help_available; + + self + } + + /// Whether command can be used only privately or not. + pub fn dm_only(mut self, dm_only: bool) -> Self { + self.0.dm_only = dm_only; + + self + } + + /// Whether command can be used only in guilds or not. + pub fn guild_only(mut self, guild_only: bool) -> Self { + self.0.guild_only = guild_only; + + self + } + + /// Minumum amount of arguments that should be passed. + pub fn min_args(mut self, min_args: i32) -> Self { + self.0.min_args = Some(min_args); + + self + } + + /// Maximum amount of arguments that can be passed. + pub fn max_args(mut self, max_args: i32) -> Self { + self.0.max_args = Some(max_args); + + self + } + + /// Maximum amount of arguments that can be passed. + pub fn required_permissions(mut self, required_permissions: Permissions) -> Self { + self.0.required_permissions = required_permissions; + + self + } + /// A function that can be called when a command is received. /// /// See [`exec_str`] if you _only_ need to return a string on command use. @@ -126,6 +169,12 @@ impl Default for Command { desc: None, usage: None, use_quotes: true, + min_args: None, + max_args: None, + required_permissions: Permissions::empty(), + dm_only: false, + guild_only: false, + help_available: true } } } diff --git a/src/ext/framework/mod.rs b/src/ext/framework/mod.rs index 077f767..fa7fdac 100644 --- a/src/ext/framework/mod.rs +++ b/src/ext/framework/mod.rs @@ -58,7 +58,7 @@ mod configuration; mod create_command; pub use self::command::{Command, CommandType}; -pub use self::configuration::Configuration; +pub use self::configuration::{AccountType, Configuration}; pub use self::create_command::CreateCommand; use self::command::{Hook, InternalCommand}; @@ -68,6 +68,8 @@ use std::thread; use ::client::Context; use ::model::Message; use ::utils; +use ::client::CACHE; +use ::model::Permissions; /// A macro to generate "named parameters". This is useful to avoid manually /// using the "arguments" parameter and manually parsing types. @@ -194,6 +196,29 @@ impl Framework { #[doc(hidden)] pub fn dispatch(&mut self, context: Context, message: Message) { + match self.configuration.account_type { + AccountType::Selfbot => { + if message.author.id != CACHE.read().unwrap().user.id { + return; + } + }, + AccountType::Bot => { + if message.author.bot { + return; + } + }, + AccountType::Automatic => { + let cache = CACHE.read().unwrap(); + if cache.user.bot { + if message.author.bot { + return; + } + } else if message.author.id != cache.user.id { + return; + } + }, + AccountType::Any => {} + } let res = command::positions(&context, &message.content, &self.configuration); let positions = match res { @@ -230,6 +255,14 @@ impl Framework { }); if let Some(command) = self.commands.get(&built) { + if message.is_private() { + if command.guild_only { + return; + } + } else if command.dm_only { + return; + } + for check in &command.checks { if !(check)(&context, &message) { continue 'outer; @@ -255,6 +288,38 @@ impl Framework { .collect::<Vec<String>>() }; + if let Some(x) = command.min_args { + if args.len() < x as usize { + return; + } + } + + if let Some(x) = command.max_args { + if args.len() > x as usize { + return; + } + } + + if !command.required_permissions.is_empty() { + let mut permissions_fulfilled = false; + + if let Some(member) = message.get_member() { + let cache = CACHE.read().unwrap(); + + if let Ok(guild_id) = member.find_guild() { + if let Some(guild) = cache.get_guild(guild_id) { + let perms = guild.permissions_for(message.channel_id, message.author.id); + + permissions_fulfilled = perms.contains(command.required_permissions); + } + } + } + + if !permissions_fulfilled { + return; + } + } + match command.exec { CommandType::StringResponse(ref x) => { let _ = &context.say(x); @@ -302,6 +367,12 @@ impl Framework { desc: None, usage: None, use_quotes: false, + dm_only: false, + guild_only: false, + help_available: true, + min_args: None, + max_args: None, + required_permissions: Permissions::empty() })); self.initialized = true; diff --git a/src/ext/mod.rs b/src/ext/mod.rs index 9605466..ba46daf 100644 --- a/src/ext/mod.rs +++ b/src/ext/mod.rs @@ -13,9 +13,9 @@ //! [`Client`]: ../client/struct.Client.html //! [`Shard`]: ../client/gateway/struct.Shard.html -#[cfg(feature = "cache")] +#[cfg(feature="cache")] pub mod cache; -#[cfg(feature = "framework")] +#[cfg(feature="framework")] pub mod framework; -#[cfg(feature = "voice")] +#[cfg(feature="voice")] pub mod voice; diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 9dd4676..591419b 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -1,8 +1,8 @@ pub mod prelude; pub mod ws_impl; -#[cfg(feature = "voice")] +#[cfg(feature="voice")] mod timer; -#[cfg(feature = "voice")] +#[cfg(feature="voice")] pub use self::timer::Timer; diff --git a/src/model/channel.rs b/src/model/channel.rs index 75dfc54..2724f1e 100644 --- a/src/model/channel.rs +++ b/src/model/channel.rs @@ -12,34 +12,34 @@ use ::constants; use ::internal::prelude::*; use ::utils::decode_array; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use hyper::Client as HyperClient; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use serde_json::builder::ObjectBuilder; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use std::fs::File; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use std::io::{Read, Write as IoWrite}; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use std::mem; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use std::path::{Path, PathBuf}; -#[cfg(all(feature="cache", feature = "methods"))] +#[cfg(all(feature="cache", feature="methods"))] use super::utils; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use ::utils::builder::{CreateEmbed, CreateInvite, EditChannel}; -#[cfg(all(feature = "cache", feature = "methods"))] +#[cfg(all(feature="cache", feature="methods"))] use ::client::CACHE; -#[cfg(all(feature = "methods"))] +#[cfg(all(feature="methods"))] use ::client::rest; -#[cfg(all(feature = "cache", feature = "methods"))] +#[cfg(all(feature="cache", feature="methods"))] use ::ext::cache::ChannelRef; impl Attachment { /// If this attachment is an image, then a tuple of the width and height /// in pixels is returned. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn dimensions(&self) -> Option<(u64, u64)> { if let (Some(width), Some(height)) = (self.width, self.height) { Some((width, height)) @@ -114,7 +114,7 @@ impl Attachment { /// [`Error::Hyper`]: ../enum.Error.html#variant.Hyper /// [`Error::Io`]: ../enum.Error.html#variant.Io /// [`Message`]: struct.Message.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn download(&self) -> Result<Vec<u8>> { let hyper = HyperClient::new(); let mut response = hyper.get(&self.url).send()?; @@ -179,7 +179,7 @@ impl Attachment { /// [`Error::Hyper`]: ../enum.Error.html#variant.Hyper /// [`Error::Io`]: ../enum.Error.html#variant.Io /// [`Message`]: struct.Message.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn download_to_directory<P: AsRef<Path>>(&self, path: P) -> Result<PathBuf> { let bytes = self.download()?; @@ -213,7 +213,7 @@ impl Channel { /// closest functionality is leaving it. /// /// [`Group`]: struct.Group.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete(&self) -> Result<()> { match *self { Channel::Group(ref group) => { @@ -276,7 +276,7 @@ impl Embed { /// This should only be useful in conjunction with [`Webhook::execute`]. /// /// [`Webhook::execute`]: struct.Webhook.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] #[inline(always)] pub fn fake<F>(f: F) -> Value where F: FnOnce(CreateEmbed) -> CreateEmbed { Value::Object(f(CreateEmbed::default()).0) @@ -293,7 +293,7 @@ impl Group { /// user. /// /// [`rest::add_group_recipient`]: ../client/rest/fn.add_group_recipient.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn add_recipient<U: Into<UserId>>(&self, user: U) -> Result<()> { let user = user.into(); @@ -306,7 +306,7 @@ impl Group { } /// Broadcasts that the current user is typing in the group. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn broadcast_typing(&self) -> Result<()> { rest::broadcast_typing(self.channel_id.0) } @@ -326,7 +326,7 @@ impl Group { /// /// [`ClientError::DeleteMessageDaysAmount`]: ../client/enum.ClientError.html#variant.DeleteMessageDaysAmount /// [`Context::delete_messages`]: ../client/struct.Context.html#delete_messages - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete_messages(&self, message_ids: &[MessageId]) -> Result<()> { if message_ids.len() < 2 || message_ids.len() > 100 { return Err(Error::Client(ClientError::BulkDeleteAmount)); @@ -350,7 +350,7 @@ impl Group { } /// Leaves the group. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn leave(&self) -> Result<Group> { rest::leave_group(self.channel_id.0) } @@ -379,7 +379,7 @@ impl Group { } /// Retrieves the list of messages that have been pinned in the group. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn pins(&self) -> Result<Vec<Message>> { rest::get_pins(self.channel_id.0) } @@ -388,7 +388,7 @@ impl Group { /// the group, then nothing is done. /// /// **Note**: This is only available to the group owner. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn remove_recipient<U: Into<UserId>>(&self, user: U) -> Result<()> { let user = user.into(); @@ -407,7 +407,7 @@ impl Group { /// **Note**: Requires the [Send Messages] permission. /// /// [Send Messages]: permissions/constant.SEND_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn send_message(&self, content: &str) -> Result<Message> { let map = ObjectBuilder::new() .insert("content", content) @@ -436,7 +436,7 @@ impl Message { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete(&self) -> Result<()> { feature_cache_enabled! {{ let req = permissions::MANAGE_MESSAGES; @@ -464,7 +464,7 @@ impl Message { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [`Reaction`]: struct.Reaction.html /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete_reactions(&self) -> Result<()> { feature_cache_enabled! {{ let req = permissions::MANAGE_MESSAGES; @@ -501,7 +501,7 @@ impl Message { /// /// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn edit<F>(&mut self, new_content: &str, embed: F) -> Result<()> where F: FnOnce(CreateEmbed) -> CreateEmbed { if let Some(length_over) = Message::overflow_length(new_content) { @@ -537,7 +537,7 @@ impl Message { /// /// Returns `None` if the channel data or guild data does not exist in the /// cache. - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn guild_id(&self) -> Option<GuildId> { let cache = CACHE.read().unwrap(); @@ -547,6 +547,31 @@ impl Message { } } + /// Gets message author as member. Won't work on private messages. + #[cfg(all(feature="cache", feature="methods"))] + pub fn get_member(&self) -> Option<Member> { + let cache = CACHE.read().unwrap(); + + if let Some(ChannelRef::Guild(channel)) = cache.get_channel(self.channel_id) { + if let Some(guild) = channel.guild_id.find() { + if let Some(member) = guild.members.get(&self.author.id) { + return Some(member.clone()) + } + } + } + + None + } + + /// True if message was sent using direct messages. + #[cfg(all(feature="cache", feature="methods"))] + pub fn is_private(&self) -> bool { + match CACHE.read().unwrap().get_channel(self.channel_id) { + Some(ChannelRef::Group(_)) | Some(ChannelRef::Private(_)) => true, + _ => false, + } + } + /// Checks the length of a string to ensure that it is within Discord's /// maximum message length limit. /// @@ -578,7 +603,7 @@ impl Message { /// /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn pin(&self) -> Result<()> { feature_cache_enabled! {{ let req = permissions::MANAGE_MESSAGES; @@ -605,7 +630,7 @@ impl Message { /// [`Emoji`]: struct.Emoji.html /// [Add Reactions]: permissions/constant.ADD_REACTIONS.html /// [permissions]: permissions - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn react<R: Into<ReactionType>>(&self, reaction_type: R) -> Result<()> { feature_cache_enabled! {{ let req = permissions::ADD_REACTIONS; @@ -642,7 +667,7 @@ impl Message { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong /// [Send Messages]: permissions/constant.SEND_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn reply(&self, content: &str) -> Result<Message> { if let Some(length_over) = Message::overflow_length(content) { return Err(Error::Client(ClientError::MessageTooLong(length_over))); @@ -681,7 +706,7 @@ impl Message { /// /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn unpin(&self) -> Result<()> { feature_cache_enabled! {{ let req = permissions::MANAGE_MESSAGES; @@ -717,7 +742,7 @@ impl PermissionOverwrite { impl PrivateChannel { /// Broadcasts that the current user is typing to the recipient. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn broadcast_typing(&self) -> Result<()> { rest::broadcast_typing(self.id.0) } @@ -749,7 +774,7 @@ impl PrivateChannel { /// [`ClientError::InvalidUser`] if the current user is not a bot user. /// /// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidOperationAsUser - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete_messages(&self, message_ids: &[MessageId]) -> Result<()> { feature_cache_enabled! {{ if !CACHE.read().unwrap().user.bot { @@ -771,14 +796,14 @@ impl PrivateChannel { /// Deletes the channel. This does not delete the contents of the channel, /// and is equivilant to closing a private channel on the client, which can /// be re-opened. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete(&self) -> Result<Channel> { rest::delete_channel(self.id.0) } /// Retrieves the list of messages that have been pinned in the private /// channel. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn pins(&self) -> Result<Vec<Message>> { rest::get_pins(self.id.0) } @@ -794,7 +819,7 @@ impl PrivateChannel { /// over the limit. /// /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn send_message(&self, content: &str) -> Result<Message> { if let Some(length_over) = Message::overflow_length(content) { return Err(Error::Client(ClientError::MessageTooLong(length_over))); @@ -832,7 +857,7 @@ impl GuildChannel { /// /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Send Messages]: permissions/constants.SEND_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn broadcast_typing(&self) -> Result<()> { rest::broadcast_typing(self.id.0) } @@ -847,7 +872,7 @@ impl GuildChannel { /// let invite = channel.create_invite(|i| i /// .max_uses(5)); /// ``` - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn create_invite<F>(&self, f: F) -> Result<RichInvite> where F: FnOnce(CreateInvite) -> CreateInvite { feature_cache_enabled! {{ @@ -892,7 +917,7 @@ impl GuildChannel { } /// Deletes this channel, returning the channel on a successful deletion. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete(&self) -> Result<Channel> { feature_cache_enabled! {{ let req = permissions::MANAGE_CHANNELS; @@ -918,7 +943,7 @@ impl GuildChannel { /// .name("test") /// .bitrate(71)); /// ``` - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn edit<F>(&mut self, f: F) -> Result<()> where F: FnOnce(EditChannel) -> EditChannel { @@ -951,13 +976,13 @@ impl GuildChannel { /// /// **Note**: Right now this performs a clone of the guild. This will be /// optimized in the future. - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn guild(&self) -> Option<Guild> { CACHE.read().unwrap().get_guild(self.guild_id).cloned() } /// Gets all channel's pins. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn pins(&self) -> Result<Vec<Message>> { rest::get_pins(self.id.0) } @@ -980,7 +1005,7 @@ impl GuildChannel { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong /// [Send Messages]: permissions/constant.SEND_MESSAGES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn send_message(&self, content: &str) -> Result<Message> { if let Some(length_over) = Message::overflow_length(content) { return Err(Error::Client(ClientError::MessageTooLong(length_over))); @@ -1008,7 +1033,7 @@ impl GuildChannel { /// **Note**: Requires the [Manage Webhooks] permission. /// /// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn webhooks(&self) -> Result<Vec<Webhook>> { rest::get_channel_webhooks(self.id.0) } @@ -1037,7 +1062,7 @@ impl Reaction { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html /// [permissions]: permissions - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete(&self) -> Result<()> { feature_cache! {{ let user = if self.user_id == CACHE.read().unwrap().user.id { @@ -1095,7 +1120,7 @@ impl Reaction { /// [`User`]: struct.User.html /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html /// [permissions]: permissions - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn users<R, U>(&self, reaction_type: R, limit: Option<u8>, diff --git a/src/model/guild.rs b/src/model/guild.rs index 0c7bb57..0d379b9 100644 --- a/src/model/guild.rs +++ b/src/model/guild.rs @@ -16,7 +16,7 @@ use super::*; use ::internal::prelude::*; use ::utils::decode_array; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use serde_json::builder::ObjectBuilder; #[cfg(all(feature="cache", feature = "methods"))] use std::mem; @@ -27,9 +27,9 @@ use ::utils::builder::EditMember; #[cfg(feature = "methods")] use ::client::rest; -#[cfg(all(feature = "cache", feature = "methods"))] +#[cfg(all(feature="cache", feature="methods"))] use ::client::CACHE; -#[cfg(all(feature = "cache", feature = "methods"))] +#[cfg(all(feature="cache", feature="methods"))] use ::utils::Colour; impl From<PartialGuild> for GuildContainer { @@ -54,7 +54,7 @@ impl Emoji { /// Finds the [`Guild`] that owns the emoji by looking through the Cache. /// /// [`Guild`]: struct.Guild.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn find_guild_id(&self) -> Option<GuildId> { CACHE.read() .unwrap() @@ -71,7 +71,7 @@ impl Emoji { /// **Note**: Only user accounts may use this method. /// /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn delete(&self) -> Result<()> { match self.find_guild_id() { Some(guild_id) => rest::delete_emoji(guild_id.0, self.id.0), @@ -86,7 +86,7 @@ impl Emoji { /// **Note**: Only user accounts may use this method. /// /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn edit(&mut self, name: &str) -> Result<()> { match self.find_guild_id() { Some(guild_id) => { @@ -132,7 +132,7 @@ impl GuildInfo { impl PartialGuild { /// Finds a role by Id within the guild. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn find_role<R: Into<RoleId>>(&self, role_id: R) -> Option<&Role> { self.roles.get(&role_id.into()) } @@ -144,7 +144,7 @@ impl PartialGuild { /// **Note**: Requires the [Change Nickname] permission. /// /// [Change Nickname]: permissions/constant.CHANGE_NICKNAME.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] #[inline] pub fn edit_nickname(&self, new_nickname: Option<&str>) -> Result<()> { rest::edit_nickname(self.id.0, new_nickname) @@ -161,7 +161,7 @@ impl PartialGuild { /// **Note**: Requires the [Manage Webhooks] permission. /// /// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] #[inline] pub fn webhooks(&self) -> Result<Vec<Webhook>> { rest::get_guild_webhooks(self.id.0) @@ -169,7 +169,7 @@ impl PartialGuild { } impl Guild { - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] fn has_perms(&self, mut permissions: Permissions) -> Result<bool> { let member = match self.get_member(CACHE.read().unwrap().user.id) { Some(member) => member, @@ -209,7 +209,7 @@ impl Guild { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn ban<U: Into<UserId>>(&self, user: U, delete_message_days: u8) -> Result<()> { if delete_message_days > 7 { @@ -239,7 +239,7 @@ impl Guild { /// [`Ban`]: struct.Ban.html /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Ban Members]: permissions/constant.BAN_MEMBERS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn bans(&self) -> Result<Vec<Ban>> { feature_cache_enabled! {{ let req = permissions::BAN_MEMBERS; @@ -274,7 +274,7 @@ impl Guild { /// [`Channel`]: struct.Channel.html /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Manage Channels]: permissions/constants.MANAGE_CHANNELS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn create_channel(&mut self, name: &str, kind: ChannelType) -> Result<Channel> { feature_cache_enabled! {{ @@ -308,7 +308,7 @@ impl Guild { /// [`Context::create_role`]: ../client/struct.Context.html#method.create_role /// [`Role`]: struct.Role.html /// [Manage Roles]: permissions/constants.MANAGE_ROLES.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn create_role<F>(&self, f: F) -> Result<Role> where F: FnOnce(EditRole) -> EditRole { feature_cache_enabled! {{ @@ -381,7 +381,7 @@ impl Guild { /// if the current user is not the guild owner. /// /// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete(&self) -> Result<PartialGuild> { feature_cache_enabled! {{ if self.owner_id != CACHE.read().unwrap().user.id { @@ -408,7 +408,7 @@ impl Guild { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [`Context::edit_guild`]: ../client/struct.Context.html#method.edit_guild /// [Manage Guild]: permissions/constants.MANAGE_GUILD.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn edit<F>(&mut self, f: F) -> Result<()> where F: FnOnce(EditGuild) -> EditGuild { feature_cache_enabled! {{ @@ -457,7 +457,7 @@ impl Guild { /// /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Change Nickname]: permissions/constant.CHANGE_NICKNAME.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn edit_nickname(&self, new_nickname: Option<&str>) -> Result<()> { feature_cache_enabled! {{ let req = permissions::CHANGE_NICKNAME; @@ -489,7 +489,7 @@ impl Guild { /// /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn get_invites(&self) -> Result<Vec<RichInvite>> { feature_cache_enabled! {{ let req = permissions::MANAGE_GUILD; @@ -563,7 +563,7 @@ impl Guild { } /// Leaves the guild. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn leave(&self) -> Result<PartialGuild> { rest::leave_guild(self.id.0) } @@ -693,7 +693,7 @@ impl Guild { /// [`GuildPrune`]: struct.GuildPrune.html /// [`Member`]: struct.Member.html /// [Kick Members]: permissions/constant.KICK_MEMBERS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn prune_count(&self, days: u16) -> Result<GuildPrune> { feature_cache_enabled! {{ let req = permissions::KICK_MEMBERS; @@ -725,7 +725,7 @@ impl Guild { /// [`GuildPrune`]: struct.GuildPrune.html /// [`Member`]: struct.Member.html /// [Kick Members]: permissions/constant.KICK_MEMBERS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn start_prune(&self, days: u16) -> Result<GuildPrune> { feature_cache_enabled! {{ let req = permissions::KICK_MEMBERS; @@ -754,7 +754,7 @@ impl Guild { /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn unban<U: Into<UserId>>(&self, user: U) -> Result<()> { feature_cache_enabled! {{ let req = permissions::BAN_MEMBERS; @@ -772,7 +772,7 @@ impl Guild { /// **Note**: Requires the [Manage Webhooks] permission. /// /// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] #[inline] pub fn webhooks(&self) -> Result<Vec<Webhook>> { rest::get_guild_webhooks(self.id.0) @@ -787,7 +787,7 @@ impl Member { /// /// [`Role`]: struct.Role.html /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn add_role<R: Into<RoleId>>(&mut self, role_id: R) -> Result<()> { let role_id = role_id.into(); @@ -814,7 +814,7 @@ impl Member { /// /// [`Role`]: struct.Role.html /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn add_roles(&mut self, role_ids: &[RoleId]) -> Result<()> { let guild_id = self.find_guild()?; self.roles.extend_from_slice(role_ids); @@ -837,7 +837,7 @@ impl Member { /// **Note**: Requires the [Ban Members] role. /// /// [Ban Members]: permissions/constant.BAN_MEMBERS.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn ban(&self, delete_message_days: u8) -> Result<()> { let guild_id = self.find_guild()?; @@ -854,7 +854,7 @@ impl Member { } /// Determines the member's colour. - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn colour(&self) -> Option<Colour> { let default = Colour::default(); let guild_id = match self.find_guild() { @@ -886,7 +886,7 @@ impl Member { /// /// [`Context::edit_member`]: ../client/struct.Context.html#method.edit_member /// [`EditMember`]: ../builder/struct.EditMember.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn edit<F>(&self, f: F) -> Result<()> where F: FnOnce(EditMember) -> EditMember { let guild_id = self.find_guild()?; @@ -898,7 +898,7 @@ impl Member { /// Finds the Id of the [`Guild`] that the member is in. /// /// [`Guild`]: struct.Guild.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn find_guild(&self) -> Result<GuildId> { CACHE.read() .unwrap() @@ -925,7 +925,7 @@ impl Member { /// /// [`Role`]: struct.Role.html /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn remove_role<R: Into<RoleId>>(&mut self, role_id: R) -> Result<()> { let role_id = role_id.into(); @@ -951,7 +951,7 @@ impl Member { /// /// [`Role`]: struct.Role.html /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn remove_roles(&mut self, role_ids: &[RoleId]) -> Result<()> { let guild_id = self.find_guild()?; self.roles.retain(|r| !role_ids.contains(r)); @@ -973,7 +973,7 @@ impl Member { /// This is shorthand for manually searching through the CACHE. /// /// If role data can not be found for the member, then `None` is returned. - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn roles(&self) -> Option<Vec<Role>> { CACHE.read().unwrap() .guilds @@ -1055,7 +1055,7 @@ impl Role { /// **Note** Requires the [Manage Roles] permission. /// /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn delete(&self) -> Result<()> { let guild_id = self.find_guild()?; @@ -1070,7 +1070,7 @@ impl Role { /// that contains the role. /// /// [`ClientError::GuildNotFound`]: ../client/enum.ClientError.html#variant.GuildNotFound - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn find_guild(&self) -> Result<GuildId> { CACHE.read() .unwrap() diff --git a/src/model/id.rs b/src/model/id.rs index d0d0b61..0d337fb 100644 --- a/src/model/id.rs +++ b/src/model/id.rs @@ -1,16 +1,16 @@ use super::*; use std::fmt; -#[cfg(all(feature = "cache", feature = "methods"))] +#[cfg(all(feature="cache", feature="methods"))] use ::client::CACHE; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use ::client::rest; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use ::internal::prelude::*; impl ChannelId { /// Search the cache for the channel with the Id. - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn find(&self) -> Option<Channel> { CACHE.read().unwrap().get_channel(*self).map(|x| x.clone_inner()) } @@ -73,7 +73,7 @@ impl From<Emoji> for EmojiId { impl GuildId { /// Search the cache for the guild. - #[cfg(all(feature = "cache", feature="methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn find(&self) -> Option<Guild> { CACHE.read().unwrap().get_guild(*self).cloned() } @@ -89,7 +89,7 @@ impl GuildId { /// Returns this Id as a `ChannelId`, which is useful when needing to use /// the guild Id to send a message to the default channel. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn to_channel(&self) -> ChannelId { ChannelId(self.0) } @@ -156,7 +156,7 @@ impl From<Role> for RoleId { impl RoleId { /// Search the cache for the role. - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn find(&self) -> Option<Role> { CACHE.read() .unwrap() @@ -174,7 +174,7 @@ impl RoleId { impl UserId { /// Search the cache for the channel with the Id. - #[cfg(all(feature = "cache", feature = "methods"))] + #[cfg(all(feature="cache", feature="methods"))] pub fn find(&self) -> Option<User> { CACHE.read().unwrap().get_user(*self).cloned() } diff --git a/src/model/invite.rs b/src/model/invite.rs index 804f5ef..4742b39 100644 --- a/src/model/invite.rs +++ b/src/model/invite.rs @@ -115,7 +115,7 @@ impl RichInvite { /// [`rest::delete_invite`]: ../client/rest/fn.delete_invite.html /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html /// [permission]: permissions/index.html - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn delete(&self) -> Result<Invite> { feature_cache_enabled! {{ let req = permissions::MANAGE_GUILD; diff --git a/src/model/mod.rs b/src/model/mod.rs index 298912f..70fdd75 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -27,9 +27,9 @@ mod id; mod misc; mod user; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] mod invite; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] mod webhook; pub use self::channel::*; @@ -40,9 +40,9 @@ pub use self::misc::*; pub use self::permissions::Permissions; pub use self::user::*; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] pub use self::invite::*; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] pub use self::webhook::*; use self::utils::*; diff --git a/src/model/user.rs b/src/model/user.rs index adc766f..c249631 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -13,22 +13,24 @@ use ::internal::prelude::*; use ::utils::decode_array; use ::model::misc::Mentionable; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use serde_json::builder::ObjectBuilder; #[cfg(feature="methods")] use std::mem; #[cfg(feature = "methods")] use super::Message; -#[cfg(feature = "methods")] +#[cfg(all(feature = "cache", feature = "methods"))] +use super::Member; +#[cfg(feature="methods")] use time::Timespec; -#[cfg(feature = "methods")] +#[cfg(feature="methods")] use ::client::rest::{self, GuildPagination}; #[cfg(feature="methods")] use super::GuildInfo; #[cfg(feature="methods")] use ::utils::builder::EditProfile; -#[cfg(feature = "cache")] +#[cfg(feature="cache")] use ::client::CACHE; impl CurrentUser { @@ -59,7 +61,7 @@ impl CurrentUser { /// .edit(|p| p /// .avatar(Some(&avatar))); /// ``` - #[cfg(feature = "methods")] + #[cfg(feature="methods")] pub fn edit<F>(&mut self, f: F) -> Result<()> where F: FnOnce(EditProfile) -> EditProfile { let mut map = ObjectBuilder::new() @@ -102,8 +104,17 @@ impl User { format!(cdn!("/avatars/{}/{}.jpg"), self.id, av)) } + /// Gets user as `Member` of a server. + #[cfg(all(feature="cache", feature="methods"))] + pub fn member<G>(&self, guild_id: G) -> Option<Member> + where G: Into<GuildId> { + let cache = CACHE.read().unwrap(); + + cache.get_member(guild_id.into(), self.id).cloned() + } + /// Retrieves the time that this user was created at. - #[cfg(feature = "methods")] + #[cfg(feature="methods")] #[inline] pub fn created_at(&self) -> Timespec { self.id.created_at() diff --git a/src/model/utils.rs b/src/model/utils.rs index e4b2445..28f5874 100644 --- a/src/model/utils.rs +++ b/src/model/utils.rs @@ -260,7 +260,7 @@ pub fn remove(map: &mut BTreeMap<String, Value>, key: &str) -> Result<Value> { } #[doc(hidden)] -#[cfg(all(feature = "cache", feature="methods"))] +#[cfg(all(feature="cache", feature="methods"))] pub fn user_has_perms(channel_id: ChannelId, mut permissions: Permissions) -> Result<bool> { diff --git a/src/utils/macros.rs b/src/utils/macros.rs index 2ba37e0..2f2ebdf 100644 --- a/src/utils/macros.rs +++ b/src/utils/macros.rs @@ -44,7 +44,7 @@ macro_rules! status { } // Enable/disable check for cache -#[cfg(feature = "cache")] +#[cfg(feature="cache")] macro_rules! feature_cache { ($enabled:block else $disabled:block) => { { @@ -53,7 +53,7 @@ macro_rules! feature_cache { } } -#[cfg(not(feature = "cache"))] +#[cfg(not(feature="cache"))] macro_rules! feature_cache { ($enabled:block else $disabled:block) => { { @@ -62,7 +62,7 @@ macro_rules! feature_cache { } } -#[cfg(feature = "cache")] +#[cfg(feature="cache")] macro_rules! feature_cache_enabled { ($enabled:block) => { { @@ -71,17 +71,17 @@ macro_rules! feature_cache_enabled { } } -#[cfg(not(feature = "cache"))] +#[cfg(not(feature="cache"))] macro_rules! feature_cache_enabled { ($enabled:block) => {{}} } -#[cfg(feature = "cache")] +#[cfg(feature="cache")] macro_rules! feature_cache_disabled { ($disabled:block) => {{}} } -#[cfg(not(feature = "cache"))] +#[cfg(not(feature="cache"))] macro_rules! feature_cache_disabled { ($disabled:block) => { { @@ -91,7 +91,7 @@ macro_rules! feature_cache_disabled { } // Enable/disable check for framework -#[cfg(feature = "framework")] +#[cfg(feature="framework")] macro_rules! feature_framework { ($enabled:block else $disabled:block) => { { @@ -100,7 +100,7 @@ macro_rules! feature_framework { } } -#[cfg(not(feature = "framework"))] +#[cfg(not(feature="framework"))] macro_rules! feature_framework { ($enabled:block else $disabled:block) => { { @@ -109,7 +109,7 @@ macro_rules! feature_framework { } } -#[cfg(feature = "framework")] +#[cfg(feature="framework")] macro_rules! feature_framework_enabled { ($enabled:block) => { { @@ -118,17 +118,17 @@ macro_rules! feature_framework_enabled { } } -#[cfg(not(feature = "framework"))] +#[cfg(not(feature="framework"))] macro_rules! feature_framework_enabled { ($enabled:block) => {{}} } -#[cfg(feature = "framework")] +#[cfg(feature="framework")] macro_rules! feature_framework_disabled { ($disabled:block) => {{}} } -#[cfg(not(feature = "framework"))] +#[cfg(not(feature="framework"))] macro_rules! feature_framework_disabled { ($disabled:block) => { { @@ -138,7 +138,7 @@ macro_rules! feature_framework_disabled { } // Enable/disable check for methods -#[cfg(feature = "methods")] +#[cfg(feature="methods")] macro_rules! feature_methods { ($enabled:block else $disabled:block) => { { @@ -147,7 +147,7 @@ macro_rules! feature_methods { } } -#[cfg(not(feature = "methods"))] +#[cfg(not(feature="methods"))] macro_rules! feature_methods { ($enabled:block else $disabled:block) => { { @@ -156,7 +156,7 @@ macro_rules! feature_methods { } } -#[cfg(feature = "methods")] +#[cfg(feature="methods")] macro_rules! feature_methods_enabled { ($enabled:block) => { { @@ -165,17 +165,17 @@ macro_rules! feature_methods_enabled { } } -#[cfg(not(feature = "methods"))] +#[cfg(not(feature="methods"))] macro_rules! feature_methods_enabled { ($enabled:block) => {{}} } -#[cfg(feature = "methods")] +#[cfg(feature="methods")] macro_rules! feature_methods_disabled { ($disabled:block) => {{}} } -#[cfg(not(feature = "methods"))] +#[cfg(not(feature="methods"))] macro_rules! feature_methods_disabled { ($disabled:block) => { { @@ -185,7 +185,7 @@ macro_rules! feature_methods_disabled { } // Enable/disable check for voice -#[cfg(feature = "voice")] +#[cfg(feature="voice")] macro_rules! feature_voice { ($enabled:block else $disabled:block) => { { @@ -194,7 +194,7 @@ macro_rules! feature_voice { } } -#[cfg(not(feature = "voice"))] +#[cfg(not(feature="voice"))] macro_rules! feature_voice { ($enabled:block else $disabled:block) => { { @@ -203,7 +203,7 @@ macro_rules! feature_voice { } } -#[cfg(feature = "voice")] +#[cfg(feature="voice")] macro_rules! feature_voice_enabled { ($enabled:block) => { { @@ -212,17 +212,17 @@ macro_rules! feature_voice_enabled { } } -#[cfg(not(feature = "voice"))] +#[cfg(not(feature="voice"))] macro_rules! feature_voice_enabled { ($enabled:block) => {{}} } -#[cfg(feature = "voice")] +#[cfg(feature="voice")] macro_rules! feature_voice_disabled { ($disabled:block) => {{}} } -#[cfg(not(feature = "voice"))] +#[cfg(not(feature="voice"))] macro_rules! feature_voice_disabled { ($disabled:block) => { { |