diff options
| -rw-r--r-- | Cargo.toml | 45 | ||||
| -rw-r--r-- | src/builder/create_embed.rs (renamed from src/utils/builder/create_embed.rs) | 36 | ||||
| -rw-r--r-- | src/builder/create_invite.rs (renamed from src/utils/builder/create_invite.rs) | 4 | ||||
| -rw-r--r-- | src/builder/create_message.rs (renamed from src/utils/builder/create_message.rs) | 10 | ||||
| -rw-r--r-- | src/builder/edit_channel.rs (renamed from src/utils/builder/edit_channel.rs) | 6 | ||||
| -rw-r--r-- | src/builder/edit_guild.rs (renamed from src/utils/builder/edit_guild.rs) | 21 | ||||
| -rw-r--r-- | src/builder/edit_member.rs (renamed from src/utils/builder/edit_member.rs) | 16 | ||||
| -rw-r--r-- | src/builder/edit_profile.rs (renamed from src/utils/builder/edit_profile.rs) | 2 | ||||
| -rw-r--r-- | src/builder/edit_role.rs (renamed from src/utils/builder/edit_role.rs) | 26 | ||||
| -rw-r--r-- | src/builder/execute_webhook.rs (renamed from src/utils/builder/execute_webhook.rs) | 16 | ||||
| -rw-r--r-- | src/builder/get_messages.rs (renamed from src/utils/builder/get_messages.rs) | 2 | ||||
| -rw-r--r-- | src/builder/mod.rs (renamed from src/utils/builder/mod.rs) | 0 | ||||
| -rw-r--r-- | src/cache/mod.rs (renamed from src/ext/cache/mod.rs) | 126 | ||||
| -rw-r--r-- | src/client/context.rs | 18 | ||||
| -rw-r--r-- | src/client/dispatch.rs | 2 | ||||
| -rw-r--r-- | src/client/error.rs | 149 | ||||
| -rw-r--r-- | src/client/mod.rs | 89 | ||||
| -rw-r--r-- | src/constants.rs | 49 | ||||
| -rw-r--r-- | src/error.rs | 96 | ||||
| -rw-r--r-- | src/ext.rs (renamed from src/ext/mod.rs) | 9 | ||||
| -rw-r--r-- | src/framework/buckets.rs (renamed from src/ext/framework/buckets.rs) | 0 | ||||
| -rw-r--r-- | src/framework/command.rs (renamed from src/ext/framework/command.rs) | 0 | ||||
| -rw-r--r-- | src/framework/configuration.rs (renamed from src/ext/framework/configuration.rs) | 5 | ||||
| -rw-r--r-- | src/framework/create_command.rs (renamed from src/ext/framework/create_command.rs) | 0 | ||||
| -rw-r--r-- | src/framework/create_group.rs (renamed from src/ext/framework/create_group.rs) | 0 | ||||
| -rw-r--r-- | src/framework/help_commands.rs (renamed from src/ext/framework/help_commands.rs) | 0 | ||||
| -rw-r--r-- | src/framework/mod.rs (renamed from src/ext/framework/mod.rs) | 10 | ||||
| -rw-r--r-- | src/gateway/error.rs (renamed from src/client/gateway/error.rs) | 25 | ||||
| -rw-r--r-- | src/gateway/mod.rs (renamed from src/client/gateway/mod.rs) | 0 | ||||
| -rw-r--r-- | src/gateway/prep.rs (renamed from src/client/gateway/prep.rs) | 5 | ||||
| -rw-r--r-- | src/gateway/shard.rs (renamed from src/client/gateway/shard.rs) | 12 | ||||
| -rw-r--r-- | src/gateway/status.rs (renamed from src/client/gateway/status.rs) | 0 | ||||
| -rw-r--r-- | src/http/error.rs | 35 | ||||
| -rw-r--r-- | src/http/mod.rs (renamed from src/client/rest/mod.rs) | 71 | ||||
| -rw-r--r-- | src/http/ratelimiting.rs (renamed from src/client/rest/ratelimiting.rs) | 12 | ||||
| -rw-r--r-- | src/internal/macros.rs (renamed from src/utils/macros.rs) | 0 | ||||
| -rw-r--r-- | src/internal/mod.rs | 5 | ||||
| -rw-r--r-- | src/internal/prelude.rs | 4 | ||||
| -rw-r--r-- | src/internal/ws_impl.rs | 2 | ||||
| -rw-r--r-- | src/lib.rs | 100 | ||||
| -rw-r--r-- | src/model/channel/attachment.rs | 2 | ||||
| -rw-r--r-- | src/model/channel/channel_id.rs | 87 | ||||
| -rw-r--r-- | src/model/channel/embed.rs | 14 | ||||
| -rw-r--r-- | src/model/channel/group.rs | 36 | ||||
| -rw-r--r-- | src/model/channel/guild_channel.rs | 73 | ||||
| -rw-r--r-- | src/model/channel/message.rs | 84 | ||||
| -rw-r--r-- | src/model/channel/mod.rs | 35 | ||||
| -rw-r--r-- | src/model/channel/private_channel.rs | 27 | ||||
| -rw-r--r-- | src/model/channel/reaction.rs | 21 | ||||
| -rw-r--r-- | src/model/error.rs | 109 | ||||
| -rw-r--r-- | src/model/event.rs | 8 | ||||
| -rw-r--r-- | src/model/gateway.rs | 1 | ||||
| -rw-r--r-- | src/model/guild/emoji.rs | 17 | ||||
| -rw-r--r-- | src/model/guild/guild_id.rs | 87 | ||||
| -rw-r--r-- | src/model/guild/member.rs | 57 | ||||
| -rw-r--r-- | src/model/guild/mod.rs | 98 | ||||
| -rw-r--r-- | src/model/guild/partial_guild.rs | 29 | ||||
| -rw-r--r-- | src/model/guild/role.rs | 23 | ||||
| -rw-r--r-- | src/model/invite.rs | 57 | ||||
| -rw-r--r-- | src/model/misc.rs | 13 | ||||
| -rw-r--r-- | src/model/mod.rs | 10 | ||||
| -rw-r--r-- | src/model/permissions.rs | 1 | ||||
| -rw-r--r-- | src/model/user.rs | 33 | ||||
| -rw-r--r-- | src/model/utils.rs | 10 | ||||
| -rw-r--r-- | src/model/webhook.rs | 55 | ||||
| -rw-r--r-- | src/prelude.rs | 4 | ||||
| -rw-r--r-- | src/utils/mod.rs | 9 | ||||
| -rw-r--r-- | src/voice/audio.rs (renamed from src/ext/voice/audio.rs) | 0 | ||||
| -rw-r--r-- | src/voice/connection.rs (renamed from src/ext/voice/connection.rs) | 0 | ||||
| -rw-r--r-- | src/voice/connection_info.rs (renamed from src/ext/voice/connection_info.rs) | 0 | ||||
| -rw-r--r-- | src/voice/error.rs (renamed from src/ext/voice/error.rs) | 0 | ||||
| -rw-r--r-- | src/voice/handler.rs (renamed from src/ext/voice/handler.rs) | 7 | ||||
| -rw-r--r-- | src/voice/manager.rs (renamed from src/ext/voice/manager.rs) | 6 | ||||
| -rw-r--r-- | src/voice/mod.rs (renamed from src/ext/voice/mod.rs) | 0 | ||||
| -rw-r--r-- | src/voice/payload.rs (renamed from src/ext/voice/payload.rs) | 0 | ||||
| -rw-r--r-- | src/voice/streamer.rs (renamed from src/ext/voice/streamer.rs) | 0 | ||||
| -rw-r--r-- | src/voice/threading.rs (renamed from src/ext/voice/threading.rs) | 0 |
77 files changed, 1132 insertions, 889 deletions
@@ -14,15 +14,11 @@ version = "0.2.0" base64 = "~0.5" bitflags = "~0.8" flate2 = "~0.2" -hyper = "~0.9" -lazy_static = "~0.2" log = "~0.3" serde = "^1.0" serde_derive = "^1.0" serde_json = "^1.0" time = "~0.1" -typemap = "~0.3" -websocket = "~0.17" [dependencies.byteorder] optional = true @@ -32,9 +28,18 @@ version = "1.0" default-features = false version = "0.2" +[dependencies.hyper] +optional = true +version = "~0.9" + +[dependencies.lazy_static] +optional = true +version = "~0.2" + [dependencies.multipart] default-features = false features = ["client", "hyper"] +optional = true version = "0.8" [dependencies.opus] @@ -46,10 +51,32 @@ default-features = false optional = true version = "0.0.12" +[dependencies.typemap] +optional = true +version = "~0.3" + +[dependencies.websocket] +optional = true +version = "~0.17" + [features] -default = ["cache", "framework"] -cache = [] -debug = [] -framework = [] +default = [ + "builder", + "cache", + "client", + "framework", + "gateway", + "model", + "http", + "utils" +] +builder = [] +cache = ["lazy_static"] +client = ["gateway", "lazy_static", "http", "typemap"] extras = [] -voice = ["byteorder", "opus", "sodiumoxide"] +framework = ["client", "model", "utils"] +gateway = ["http", "websocket"] +http = ["hyper", "lazy_static", "multipart"] +model = ["builder", "http"] +utils = [] +voice = ["byteorder", "gateway", "opus", "sodiumoxide"] diff --git a/src/utils/builder/create_embed.rs b/src/builder/create_embed.rs index 457a960..ff4e2c4 100644 --- a/src/utils/builder/create_embed.rs +++ b/src/builder/create_embed.rs @@ -10,7 +10,7 @@ //! //! Documentation for embeds can be found [here]. //! -//! [`Context::send_message`]: ../../client/struct.Context.html#method.send_message +//! [`Context::send_message`]: ../client/struct.Context.html#method.send_message //! [`CreateEmbed`]: struct.CreateEmbed.html //! [`ExecuteWebhook::embeds`]: struct.ExecuteWebhook.html#method.embeds //! [here]: https://discordapp.com/developers/docs/resources/channel#embed-object @@ -20,6 +20,8 @@ use std::default::Default; use time::Tm; use ::internal::prelude::*; use ::model::Embed; + +#[cfg(feature="utils")] use ::utils::Colour; /// A builder to create a fake [`Embed`] object, for use with the @@ -30,8 +32,8 @@ use ::utils::Colour; /// Refer to the documentation for [`Context::send_message`] for a very in-depth /// example on how to use this. /// -/// [`Context::send_message`]: ../../client/struct.Context.html#method.send_message -/// [`Embed`]: ../../model/struct.Embed.html +/// [`Context::send_message`]: ../client/struct.Context.html#method.send_message +/// [`Embed`]: ../model/struct.Embed.html /// [`ExecuteWebhook::embeds`]: struct.ExecuteWebhook.html#method.embeds #[derive(Clone, Debug)] pub struct CreateEmbed(pub Map<String, Value>); @@ -57,17 +59,39 @@ impl CreateEmbed { /// This is an alias of [`colour`]. /// /// [`colour`]: #method.colour + #[cfg(feature="utils")] + #[inline] pub fn color<C: Into<Colour>>(self, colour: C) -> Self { self.colour(colour.into()) } /// Set the colour of the left-hand side of the embed. + #[cfg(feature="utils")] pub fn colour<C: Into<Colour>>(mut self, colour: C) -> Self { self.0.insert("color".to_owned(), Value::Number(Number::from(colour.into().0 as u64))); CreateEmbed(self.0) } + /// Set the colour of the left-hand side of the embed. + /// + /// This is an alias of [`colour`]. + /// + /// [`colour`]: #method.colour + #[cfg(not(feature="utils"))] + #[inline] + pub fn color(self, colour: u32) -> Self { + self.colour(colour) + } + + /// Set the colour of the left-hand side of the embed. + #[cfg(not(feature="utils"))] + pub fn colour(mut self, colour: u32) -> Self { + self.0.insert("color".to_owned(), Value::Number(Number::from(colour))); + + CreateEmbed(self.0) + } + /// Set the description of the embed. /// /// **Note**: This can't be longer than 2048 characters. @@ -269,7 +293,7 @@ impl From<Embed> for CreateEmbed { /// /// Requires that you specify a [`name`]. /// -/// [`Embed`]: ../../model/struct.Embed.html +/// [`Embed`]: ../model/struct.Embed.html /// [`CreateEmbed::author`]: struct.CreateEmbed.html#method.author /// [`name`]: #method.name #[derive(Clone, Debug, Default)] @@ -304,7 +328,7 @@ impl CreateEmbedAuthor { /// This does not require any field be set. `inline` is set to `true` by /// default. /// -/// [`Embed`]: ../../model/struct.Embed.html +/// [`Embed`]: ../model/struct.Embed.html /// [`CreateEmbed::field`]: struct.CreateEmbed.html#method.field #[derive(Clone, Debug)] pub struct CreateEmbedField(pub Map<String, Value>); @@ -348,7 +372,7 @@ impl Default for CreateEmbedField { /// /// This does not require any field be set. /// -/// [`Embed`]: ../../model/struct.Embed.html +/// [`Embed`]: ../model/struct.Embed.html /// [`CreateEmbed::footer`]: struct.CreateEmbed.html#method.footer #[derive(Clone, Debug, Default)] pub struct CreateEmbedFooter(pub Map<String, Value>); diff --git a/src/utils/builder/create_invite.rs b/src/builder/create_invite.rs index 6ff2a67..67e33fc 100644 --- a/src/utils/builder/create_invite.rs +++ b/src/builder/create_invite.rs @@ -26,8 +26,8 @@ use ::internal::prelude::*; /// }); /// ``` /// -/// [`Context::create_invite`]: ../../client/struct.Context.html#method.create_invite -/// [`RichInvite`]: ../../model/struct.Invite.html +/// [`Context::create_invite`]: ../client/struct.Context.html#method.create_invite +/// [`RichInvite`]: ../model/struct.Invite.html #[derive(Clone, Debug)] pub struct CreateInvite(pub JsonMap); diff --git a/src/utils/builder/create_message.rs b/src/builder/create_message.rs index 5c3b6eb..9a2349a 100644 --- a/src/utils/builder/create_message.rs +++ b/src/builder/create_message.rs @@ -1,7 +1,7 @@ use super::CreateEmbed; use ::internal::prelude::*; -/// A builder to specify the contents of an [`rest::send_message`] request, +/// A builder to specify the contents of an [`http::send_message`] request, /// primarily meant for use through [`Context::send_message`]. /// /// There are two situations where different field requirements are present: @@ -31,11 +31,11 @@ use ::internal::prelude::*; /// .description("With a description"))); /// ``` /// -/// [`Context::say`]: ../../client/struct.Context.html#method.say -/// [`Context::send_message`]: ../../client/struct.Context.html#method.send_message +/// [`Context::say`]: ../client/struct.Context.html#method.say +/// [`Context::send_message`]: ../client/struct.Context.html#method.send_message /// [`content`]: #method.content /// [`embed`]: #method.embed -/// [`rest::send_message`]: ../../client/rest/fn.send_message.html +/// [`http::send_message`]: ../http/fn.send_message.html #[derive(Clone, Debug)] pub struct CreateMessage(pub Map<String, Value>); @@ -75,7 +75,7 @@ impl Default for CreateMessage { /// Creates a map for sending a [`Message`], setting [`tts`] to `false` by /// default. /// - /// [`Message`]: ../../model/struct.Message.html + /// [`Message`]: ../model/struct.Message.html /// [`tts`]: #method.tts fn default() -> CreateMessage { let mut map = Map::default(); diff --git a/src/utils/builder/edit_channel.rs b/src/builder/edit_channel.rs index 4d0955e..2bf8979 100644 --- a/src/utils/builder/edit_channel.rs +++ b/src/builder/edit_channel.rs @@ -31,7 +31,7 @@ impl EditChannel { /// /// This is for [voice] channels only. /// - /// [voice]: ../../model/enum.ChannelType.html#variant.Voice + /// [voice]: ../model/enum.ChannelType.html#variant.Voice pub fn bitrate(mut self, bitrate: u64) -> Self { self.0.insert("bitrate".to_owned(), Value::Number(Number::from(bitrate))); @@ -60,7 +60,7 @@ impl EditChannel { /// /// This is for [text] channels only. /// - /// [text]: ../../model/enum.ChannelType.html#variant.Text + /// [text]: ../model/enum.ChannelType.html#variant.Text pub fn topic(mut self, topic: &str) -> Self { self.0.insert("topic".to_owned(), Value::String(topic.to_owned())); @@ -71,7 +71,7 @@ impl EditChannel { /// /// This is for [voice] channels only. /// - /// [voice]: ../../model/enum.ChannelType.html#variant.Voice + /// [voice]: ../model/enum.ChannelType.html#variant.Voice pub fn user_limit(mut self, user_limit: u64) -> Self { self.0.insert("user_limit".to_owned(), Value::Number(Number::from(user_limit))); diff --git a/src/utils/builder/edit_guild.rs b/src/builder/edit_guild.rs index e423fc2..aa08341 100644 --- a/src/utils/builder/edit_guild.rs +++ b/src/builder/edit_guild.rs @@ -7,10 +7,10 @@ use ::model::{ChannelId, Region, UserId, VerificationLevel}; /// **Note**: Editing a guild requires that the current user have the /// [Manage Guild] permission. /// -/// [`Context::edit_guild`]: ../../client/struct.Context.html -/// [`Guild`]: ../../model/struct.Guild.html -/// [`LiveGuild::edit`]: ../../model/struct.LiveGuild.html#method.edit -/// [Manage Guild]: ../../model/permissions/constant.MANAGE_GUILD.html +/// [`Context::edit_guild`]: ../client/struct.Context.html +/// [`Guild`]: ../model/struct.Guild.html +/// [`LiveGuild::edit`]: ../model/struct.LiveGuild.html#method.edit +/// [Manage Guild]: ../model/permissions/constant.MANAGE_GUILD.html #[derive(Clone, Debug, Default)] pub struct EditGuild(pub Map<String, Value>); @@ -60,7 +60,7 @@ impl EditGuild { /// let _ = guild.edit(|g| g.icon(base64_icon)); /// ``` /// - /// [`utils::read_image`]: ../../utils/fn.read_image.html + /// [`utils::read_image`]: ../utils/fn.read_image.html pub fn icon(mut self, icon: Option<&str>) -> Self { self.0.insert("icon".to_owned(), icon.map_or_else(|| Value::Null, |x| Value::String(x.to_owned()))); @@ -101,7 +101,7 @@ impl EditGuild { /// } /// ``` /// - /// [`Region::UsWest`]: ../../model/enum.Region.html#variant.UsWest + /// [`Region::UsWest`]: ../model/enum.Region.html#variant.UsWest pub fn region(mut self, region: Region) -> Self { self.0.insert("region".to_owned(), Value::String(region.name().to_owned())); @@ -113,8 +113,8 @@ impl EditGuild { /// Requires that the guild have the [`InviteSplash`] feature enabled. /// You can check this through a guild's [`features`] list. /// - /// [`InviteSplash`]: ../../model/enum.Feature.html#variant.InviteSplash - /// [`features`]: ../../model/struct.LiveGuild.html#structfield.features + /// [`InviteSplash`]: ../model/enum.Feature.html#variant.InviteSplash + /// [`features`]: ../model/struct.LiveGuild.html#structfield.features pub fn splash(mut self, splash: Option<&str>) -> Self { let splash = splash.map_or(Value::Null, |x| Value::String(x.to_owned())); @@ -129,7 +129,6 @@ impl EditGuild { /// Refer to the documentation for [`VerificationLevel`] for more /// information on each variant. /// - /// [`VerificationLevel`]: ../../model/enum.VerificationLevel.html /// /// # Examples /// @@ -152,8 +151,8 @@ impl EditGuild { /// } /// ``` /// - /// [`VerificationLevel`]: ../../model/enum.VerificationLevel.html - /// [`VerificationLevel::High`]: ../../model/enum.VerificationLevel.html#variant.High + /// [`VerificationLevel`]: ../model/enum.VerificationLevel.html + /// [`VerificationLevel::High`]: ../model/enum.VerificationLevel.html#variant.High pub fn verification_level<V>(mut self, verification_level: V) -> Self where V: Into<VerificationLevel> { let num = Value::Number(Number::from(verification_level.into().num())); diff --git a/src/utils/builder/edit_member.rs b/src/builder/edit_member.rs index af35bf9..044d8f2 100644 --- a/src/utils/builder/edit_member.rs +++ b/src/builder/edit_member.rs @@ -4,9 +4,9 @@ use ::internal::prelude::*; /// A builder which edits the properties of a [`Member`], to be used in /// conjunction with [`Context::edit_member`] and [`Member::edit`]. /// -/// [`Context::edit_member`]: ../../client/struct.Context.html#method.edit_member -/// [`Member`]: ../../model/struct.Member.html -/// [`Member::edit`]: ../../model/struct.Member.html#method.edit +/// [`Context::edit_member`]: ../client/struct.Context.html#method.edit_member +/// [`Member`]: ../model/struct.Member.html +/// [`Member::edit`]: ../model/struct.Member.html#method.edit #[derive(Clone, Debug, Default)] pub struct EditMember(pub JsonMap); @@ -15,7 +15,7 @@ impl EditMember { /// /// Requires the [Deafen Members] permission. /// - /// [Deafen Members]: ../../model/permissions/constant.DEAFEN_MEMBERS.html + /// [Deafen Members]: ../model/permissions/constant.DEAFEN_MEMBERS.html pub fn deafen(mut self, deafen: bool) -> Self { self.0.insert("deaf".to_owned(), Value::Bool(deafen)); @@ -26,7 +26,7 @@ impl EditMember { /// /// Requires the [Mute Members] permission. /// - /// [Mute Members]: ../../model/permissions/constant.MUTE_MEMBERS.html + /// [Mute Members]: ../model/permissions/constant.MUTE_MEMBERS.html pub fn mute(mut self, mute: bool) -> Self { self.0.insert("mute".to_owned(), Value::Bool(mute)); @@ -38,7 +38,7 @@ impl EditMember { /// /// Requires the [Manage Nicknames] permission. /// - /// [Manage Nicknames]: ../../model/permissions/constant.MANAGE_NICKNAMES.html + /// [Manage Nicknames]: ../model/permissions/constant.MANAGE_NICKNAMES.html pub fn nickname(mut self, nickname: &str) -> Self { self.0.insert("nick".to_owned(), Value::String(nickname.to_owned())); @@ -49,7 +49,7 @@ impl EditMember { /// /// Requires the [Manage Roles] permission to modify. /// - /// [Manage Roles]: ../../model/permissions/constant.MANAGE_ROLES.html + /// [Manage Roles]: ../model/permissions/constant.MANAGE_ROLES.html pub fn roles(mut self, roles: &[RoleId]) -> Self { let role_ids = roles.iter().map(|x| Value::Number(Number::from(x.0))).collect(); @@ -62,7 +62,7 @@ impl EditMember { /// /// Requires the [Move Members] permission. /// - /// [Move Members]: ../../model/permissions/constant.MOVE_MEMBERS.html + /// [Move Members]: ../model/permissions/constant.MOVE_MEMBERS.html pub fn voice_channel<C: Into<ChannelId>>(mut self, channel_id: C) -> Self { self.0.insert("channel_id".to_owned(), Value::Number(Number::from(channel_id.into().0))); diff --git a/src/utils/builder/edit_profile.rs b/src/builder/edit_profile.rs index 64bd7a9..d63a512 100644 --- a/src/utils/builder/edit_profile.rs +++ b/src/builder/edit_profile.rs @@ -3,7 +3,7 @@ use ::internal::prelude::*; /// A builder to edit the current user's settings, to be used in conjunction /// with [`Context::edit_profile`]. /// -/// [`Context::edit_profile`]: ../../client/struct.Context.html#method.edit_profile +/// [`Context::edit_profile`]: ../client/struct.Context.html#method.edit_profile #[derive(Clone, Debug, Default)] pub struct EditProfile(pub JsonMap); diff --git a/src/utils/builder/edit_role.rs b/src/builder/edit_role.rs index 6a44912..64cc42b 100644 --- a/src/utils/builder/edit_role.rs +++ b/src/builder/edit_role.rs @@ -26,21 +26,31 @@ use ::model::{Permissions, Role, permissions}; /// .name("a test role")); /// ``` /// -/// [`Context::create_role`]: ../../client/struct.Context.html#method.create_role -/// [`Context::edit_role`]: ../../client/struct.Context.html#method.edit_role -/// [`Guild::create_role`]: ../../model/struct.Guild.html#method.create_role -/// [`Role`]: ../../model/struct.Role.html -/// [`Role::edit`]: ../../model/struct.Role.html#method.edit +/// [`Context::create_role`]: ../client/struct.Context.html#method.create_role +/// [`Context::edit_role`]: ../client/struct.Context.html#method.edit_role +/// [`Guild::create_role`]: ../model/struct.Guild.html#method.create_role +/// [`Role`]: ../model/struct.Role.html +/// [`Role::edit`]: ../model/struct.Role.html#method.edit #[derive(Clone, Debug)] pub struct EditRole(pub JsonMap); impl EditRole { /// Creates a new builder with the values of the given [`Role`]. /// - /// [`Role`]: ../../model/struct.Role.html + /// [`Role`]: ../model/struct.Role.html pub fn new(role: &Role) -> Self { let mut map = Map::new(); - map.insert("color".to_owned(), Value::Number(Number::from(role.colour.0))); + + #[cfg(feature="utils")] + { + map.insert("color".to_owned(), Value::Number(Number::from(role.colour.0))); + } + + #[cfg(not(feature="utils"))] + { + map.insert("color".to_owned(), Value::Number(Number::from(role.colour))); + } + map.insert("hoist".to_owned(), Value::Bool(role.hoist)); map.insert("managed".to_owned(), Value::Bool(role.managed)); map.insert("mentionable".to_owned(), Value::Bool(role.mentionable)); @@ -108,7 +118,7 @@ impl Default for EditRole { /// - **permissions**: the [general permissions set] /// - **position**: 1 /// - /// [general permissions set]: ../../model/permissions/constant.PRESET_GENERAL.html + /// [general permissions set]: ../model/permissions/constant.PRESET_GENERAL.html fn default() -> EditRole { let mut map = Map::new(); let permissions = Number::from(permissions::PRESET_GENERAL.bits()); diff --git a/src/utils/builder/execute_webhook.rs b/src/builder/execute_webhook.rs index ee898de..67e10be 100644 --- a/src/utils/builder/execute_webhook.rs +++ b/src/builder/execute_webhook.rs @@ -16,14 +16,14 @@ use ::internal::prelude::*; /// payload of [`Webhook::execute`]: /// /// ```rust,ignore -/// use serenity::client::rest; +/// use serenity::http; /// use serenity::model::Embed; /// use serenity::utils::Colour; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// -/// let webhook = rest::get_webhook_with_token(id, token) +/// let webhook = http::get_webhook_with_token(id, token) /// .expect("valid webhook"); /// /// let website = Embed::fake(|e| e @@ -49,9 +49,9 @@ use ::internal::prelude::*; /// .embeds(vec![website, resources])); /// ``` /// -/// [`Webhook`]: ../../model/struct.Webhook.html -/// [`Webhook::execute`]: ../../model/struct.Webhook.html#method.execute -/// [`execute_webhook`]: ../../client/rest/fn.execute_webhook.html +/// [`Webhook`]: ../model/struct.Webhook.html +/// [`Webhook::execute`]: ../model/struct.Webhook.html#method.execute +/// [`execute_webhook`]: ../http/fn.execute_webhook.html #[derive(Clone, Debug)] pub struct ExecuteWebhook(pub JsonMap); @@ -85,8 +85,8 @@ impl ExecuteWebhook { /// Refer to the [struct-level documentation] for an example on how to use /// embeds. /// - /// [`Embed::fake`]: ../../model/struct.Embed.html#method.fake - /// [`Webhook::execute`]: ../../model/struct.Webhook.html#method.execute + /// [`Embed::fake`]: ../model/struct.Embed.html#method.fake + /// [`Webhook::execute`]: ../model/struct.Webhook.html#method.execute /// [struct-level documentation]: #examples pub fn embeds(mut self, embeds: Vec<Value>) -> Self { self.0.insert("embeds".to_owned(), Value::Array(embeds)); @@ -118,7 +118,7 @@ impl Default for ExecuteWebhook { /// there is a bug that Discord defaults `tts` to `true`, at least /// serenity won't be a part of it. /// - /// [`Webhook`]: ../../model/struct.Webhook.html + /// [`Webhook`]: ../model/struct.Webhook.html /// [`tts`]: #method.tts fn default() -> ExecuteWebhook { let mut map = Map::new(); diff --git a/src/utils/builder/get_messages.rs b/src/builder/get_messages.rs index cc4658c..b9142a1 100644 --- a/src/utils/builder/get_messages.rs +++ b/src/builder/get_messages.rs @@ -20,7 +20,7 @@ use ::model::MessageId; /// This should be used only for retrieving messages; see /// [`Client::get_messages`] for examples. /// -/// [`Client::get_messages`]: ../../client/struct.Client.html#method.get_messages +/// [`Client::get_messages`]: ../client/struct.Client.html#method.get_messages #[derive(Clone, Debug, Default)] pub struct GetMessages(pub BTreeMap<String, u64>); diff --git a/src/utils/builder/mod.rs b/src/builder/mod.rs index 3fc0f05..3fc0f05 100644 --- a/src/utils/builder/mod.rs +++ b/src/builder/mod.rs diff --git a/src/ext/cache/mod.rs b/src/cache/mod.rs index f1326d4..7bea675 100644 --- a/src/ext/cache/mod.rs +++ b/src/cache/mod.rs @@ -2,7 +2,7 @@ //! data from the event is possible. //! //! This acts as a cache, to avoid making requests over the REST API through -//! the [`rest`] module where possible. All fields are public, and do not have +//! the [`http`] module where possible. All fields are public, and do not have //! getters, to allow you more flexibility with the stored data. However, this //! allows data to be "corrupted", and _may or may not_ cause misfunctions //! within the library. Mutate data at your own discretion. @@ -22,7 +22,7 @@ //! This allows you to save a step, by only needing to perform the //! [`Context::get_channel`] call and not need to first search through the cache //! - and if not found - _then_ perform an HTTP request through the Context or -//! [`rest`] module. +//! [`http`] module. //! //! Additionally, note that some information received through events can _not_ //! be retrieved through the REST API. This is information such as [`Role`]s in @@ -49,17 +49,17 @@ //! while needing to hit the REST API as little as possible, then the answer //! is "yes". //! -//! [`Context`]: ../../client/struct.Context.html -//! [`Context::get_channel`]: ../../client/struct.Context.html#method.get_channel -//! [`Emoji`]: ../../model/struct.Emoji.html -//! [`Group`]: ../../model/struct.Group.html -//! [`LiveGuild`]: ../../model/struct.LiveGuild.html -//! [`LiveGuild::edit`]: ../../model/struct.LiveGuild.html#method.edit -//! [`Message`]: ../../model/struct.Message.html -//! [`PublicChannel`]: ../../model/struct.PublicChannel.html -//! [`Role`]: ../../model/struct.Role.html -//! [`client::CACHE`]: ../../client/struct.CACHE.html -//! [`rest`]: ../../client/rest/index.html +//! [`Context`]: ../client/struct.Context.html +//! [`Context::get_channel`]: ../client/struct.Context.html#method.get_channel +//! [`Emoji`]: ../model/struct.Emoji.html +//! [`Group`]: ../model/struct.Group.html +//! [`LiveGuild`]: ../model/struct.LiveGuild.html +//! [`LiveGuild::edit`]: ../model/struct.LiveGuild.html#method.edit +//! [`Message`]: ../model/struct.Message.html +//! [`PublicChannel`]: ../model/struct.PublicChannel.html +//! [`Role`]: ../model/struct.Role.html +//! [`CACHE`]: ../struct.CACHE.html +//! [`http`]: ../http/index.html use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; @@ -69,11 +69,11 @@ use std::mem; use ::model::*; use ::model::event::*; -/// A cache of all events received over a [`Connection`], where storing at least +/// A cache of all events received over a [`Shard`], where storing at least /// some data from the event is possible. /// /// This acts as a cache, to avoid making requests over the REST API through the -/// [`rest`] module where possible. All fields are public, and do not have +/// [`http`] module where possible. All fields are public, and do not have /// getters, to allow you more flexibility with the stored data. However, this /// allows data to be "corrupted", and _may or may not_ cause misfunctions /// within the library. Mutate data at your own discretion. @@ -88,18 +88,18 @@ use ::model::event::*; /// /// This allows you to only need to perform the `Context::get_channel` call, /// and not need to first search through the cache - and if not found - _then_ -/// perform an HTTP request through the Context or `rest` module. +/// perform an HTTP request through the Context or `http` module. /// /// Additionally, note that some information received through events can _not_ /// be retrieved through the REST API. This is information such as [`Role`]s in /// [`Guild`]s. /// -/// [`Connection`]: ../../client/struct.Connection.html -/// [`Context`]: ../../client/struct.Context.html -/// [`Context::get_channel`]: ../../client/struct.Context.html#method.get_channel -/// [`Guild`]: ../../model/struct.Guild.html -/// [`Role`]: ../../model/struct.Role.html -/// [`rest`]: ../../client/rest/index.html +/// [`Shard`]: ../gateway/struct.Shard.html +/// [`Context`]: ../client/struct.Context.html +/// [`Context::get_channel`]: ../client/struct.Context.html#method.get_channel +/// [`Guild`]: ../model/struct.Guild.html +/// [`Role`]: ../model/struct.Role.html +/// [`http`]: ../http/index.html #[derive(Clone, Debug)] pub struct Cache { /// A map of channels in [`Guild`]s that the current user has received data @@ -109,9 +109,9 @@ pub struct Cache { /// received and processed by the cache, the relevant channels are also /// removed from this map. /// - /// [`Event::GuildDelete`]: ../../model/event/struct.GuildDeleteEvent.html - /// [`Event::GuildUnavailable`]: ../../model/event/struct.GuildUnavailableEvent.html - /// [`Guild`]: ../../model/struct.Guild.html + /// [`Event::GuildDelete`]: ../model/event/struct.GuildDeleteEvent.html + /// [`Event::GuildUnavailable`]: ../model/event/struct.GuildUnavailableEvent.html + /// [`Guild`]: ../model/struct.Guild.html pub channels: HashMap<ChannelId, Arc<RwLock<GuildChannel>>>, /// A map of the groups that the current user is in. /// @@ -122,8 +122,8 @@ pub struct Cache { /// A map of guilds with full data available. This includes data like /// [`Role`]s and [`Emoji`]s that are not available through the REST API. /// - /// [`Emoji`]: ../../model/struct.Emoji.html - /// [`Role`]: ../../model/struct.Role.html + /// [`Emoji`]: ../model/struct.Emoji.html + /// [`Role`]: ../model/struct.Role.html pub guilds: HashMap<GuildId, Arc<RwLock<Guild>>>, /// A map of notes that a user has made for individual users. /// @@ -148,8 +148,8 @@ pub struct Cache { /// is received. Guilds are "sent in" over time through the receiving of /// [`Event::GuildCreate`]s. /// - /// [`Event::GuildCreate`]: ../../model/enum.Event.html#variant.GuildCreate - /// [`Event::GuildUnavailable`]: ../../model/enum.Event.html#variant.GuildUnavailable + /// [`Event::GuildCreate`]: ../model/enum.Event.html#variant.GuildCreate + /// [`Event::GuildUnavailable`]: ../model/enum.Event.html#variant.GuildUnavailable pub unavailable_guilds: HashSet<GuildId>, /// The current user "logged in" and for which events are being received /// for. @@ -159,8 +159,8 @@ pub struct Cache { /// /// Refer to the documentation for [`CurrentUser`] for more information. /// - /// [`CurrentUser`]: ../../model/struct.CurrentUser.html - /// [`User`]: ../../model/struct.User.html + /// [`CurrentUser`]: ../model/struct.CurrentUser.html + /// [`User`]: ../model/struct.User.html pub user: CurrentUser, /// A map of users that the current user sees. /// @@ -179,14 +179,14 @@ pub struct Cache { /// events such as [`GuildMemberRemove`][`GuildMemberRemoveEvent`], as other /// structs such as members or recipients may still exist. /// - /// [`ChannelRecipientAddEvent`]: ../../model/event/struct.ChannelRecipientAddEvent.html - /// [`GuildMemberAddEvent`]: ../../model/event/struct.GuildMemberAddEvent.html - /// [`GuildMemberRemoveEvent`]: ../../model/event/struct.GuildMemberRemoveEvent.html - /// [`GuildMemberUpdateEvent`]: ../../model/event/struct.GuildMemberUpdateEvent.html - /// [`GuildMembersChunkEvent`]: ../../model/event/struct.GuildMembersChunkEvent.html - /// [`GuildSyncEvent`]: ../../model/event/struct.GuildSyncEvent.html - /// [`PresenceUpdateEvent`]: ../../model/event/struct.PresenceUpdateEvent.html - /// [`Ready`]: ../../model/event/struct.ReadyEvent.html + /// [`ChannelRecipientAddEvent`]: ../model/event/struct.ChannelRecipientAddEvent.html + /// [`GuildMemberAddEvent`]: ../model/event/struct.GuildMemberAddEvent.html + /// [`GuildMemberRemoveEvent`]: ../model/event/struct.GuildMemberRemoveEvent.html + /// [`GuildMemberUpdateEvent`]: ../model/event/struct.GuildMemberUpdateEvent.html + /// [`GuildMembersChunkEvent`]: ../model/event/struct.GuildMembersChunkEvent.html + /// [`GuildSyncEvent`]: ../model/event/struct.GuildSyncEvent.html + /// [`PresenceUpdateEvent`]: ../model/event/struct.PresenceUpdateEvent.html + /// [`Ready`]: ../model/event/struct.ReadyEvent.html pub users: HashMap<UserId, Arc<RwLock<User>>>, } @@ -200,8 +200,8 @@ impl Cache { /// This can be used in combination with [`Shard::chunk_guilds`], and can be /// used to determine how many members have not yet been downloaded. /// - /// [`Member`]: ../../model/struct.Member.html - /// [`User`]: ../../model/struct.User.html + /// [`Member`]: ../model/struct.Member.html + /// [`User`]: ../model/struct.User.html pub fn unknown_members(&self) -> u64 { let mut total = 0; @@ -226,8 +226,8 @@ impl Cache { /// If there are 6 private channels and 2 groups in the cache, then `8` Ids /// will be returned. /// - /// [`Group`]: ../../model/struct.Group.html - /// [`PrivateChannel`]: ../../model/struct.PrivateChannel.html + /// [`Group`]: ../model/struct.Group.html + /// [`PrivateChannel`]: ../model/struct.PrivateChannel.html pub fn all_private_channels(&self) -> Vec<ChannelId> { self.groups .keys() @@ -242,9 +242,9 @@ impl Cache { /// retrieved over all shards are included in this count -- not just the /// current [`Context`]'s shard, if accessing from one. /// - /// [`Context`]: ../../client/struct.Context.html - /// [`Guild`]: ../../model/struct.Guild.html - /// [`Shard`]: ../../client/gateway/struct.Shard.html + /// [`Context`]: ../client/struct.Context.html + /// [`Guild`]: ../model/struct.Guild.html + /// [`Shard`]: ../gateway/struct.Shard.html pub fn all_guilds(&self) -> Vec<GuildId> { self.guilds .values() @@ -265,9 +265,9 @@ impl Cache { /// - [`PrivateChannel`]: [`get_private_channel`] or [`private_channels`] /// - [`Group`]: [`get_group`] or [`groups`] /// - /// [`Channel`]: ../../model/enum.Channel.html - /// [`Group`]: ../../model/struct.Group.html - /// [`Guild`]: ../../model/struct.Guild.html + /// [`Channel`]: ../model/enum.Channel.html + /// [`Group`]: ../model/struct.Group.html + /// [`Guild`]: ../model/struct.Guild.html /// [`channels`]: #structfield.channels /// [`get_group`]: #method.get_group /// [`get_guild_channel`]: #method.get_guild_channel @@ -297,7 +297,7 @@ impl Cache { /// The only advantage of this method is that you can pass in anything that /// is indirectly a [`GuildId`]. /// - /// [`GuildId`]: ../../model/struct.GuildId.html + /// [`GuildId`]: ../model/struct.GuildId.html #[inline] pub fn guild<G: Into<GuildId>>(&self, id: G) -> Option<Arc<RwLock<Guild>>> { self.guilds.get(&id.into()).cloned() @@ -315,7 +315,7 @@ impl Cache { /// [`Client::on_message`] event dispatch: /// /// ```rust,ignore - /// use serenity::client::CACHE; + /// use serenity::CACHE; /// /// let cache = CACHE.read().unwrap(); /// @@ -331,9 +331,9 @@ impl Cache { /// }; /// ``` /// - /// [`ChannelId`]: ../../model/struct.ChannelId.html - /// [`Client::on_message`]: ../../client/struct.Client.html#method.on_message - /// [`Guild`]: ../../model/struct.Guild.html + /// [`ChannelId`]: ../model/struct.ChannelId.html + /// [`Client::on_message`]: ../client/struct.Client.html#method.on_message + /// [`Guild`]: ../model/struct.Guild.html /// [`get_channel`]: #method.get_channel #[inline] pub fn guild_channel<C: Into<ChannelId>>(&self, id: C) -> Option<Arc<RwLock<GuildChannel>>> { @@ -346,8 +346,8 @@ impl Cache { /// The only advantage of this method is that you can pass in anything that /// is indirectly a [`ChannelId`]. /// - /// [`ChannelId`]: ../../model/struct.ChannelId.html - /// [`Group`]: ../../model/struct.Group.html + /// [`ChannelId`]: ../model/struct.ChannelId.html + /// [`Group`]: ../model/struct.Group.html #[inline] pub fn group<C: Into<ChannelId>>(&self, id: C) -> Option<Arc<RwLock<Group>>> { self.groups.get(&id.into()).cloned() @@ -365,7 +365,7 @@ impl Cache { /// [`Client::on_message`] context: /// /// ```rust,ignore - /// use serenity::client::CACHE; + /// use serenity::CACHE; /// /// let cache = CACHE.read().unwrap(); /// let member = { @@ -395,9 +395,9 @@ impl Cache { /// } /// ``` /// - /// [`Client::on_message`]: ../../client/struct.Client.html#method.on_message - /// [`Guild`]: ../../model/struct.Guild.html - /// [`members`]: ../../model/struct.Guild.html#structfield.members + /// [`Client::on_message`]: ../client/struct.Client.html#method.on_message + /// [`Guild`]: ../model/struct.Guild.html + /// [`members`]: ../model/struct.Guild.html#structfield.members pub fn member<G, U>(&self, guild_id: G, user_id: U) -> Option<Member> where G: Into<GuildId>, U: Into<UserId> { self.guilds @@ -421,8 +421,8 @@ impl Cache { /// **Note**: This will clone the entire role. Instead, retrieve the guild /// and retrieve from the guild's [`roles`] map to avoid this. /// - /// [`Guild`]: ../../model/struct.Guild.html - /// [`roles`]: ../../model/struct.Guild.html#structfield.roles + /// [`Guild`]: ../model/struct.Guild.html + /// [`roles`]: ../model/struct.Guild.html#structfield.roles pub fn role<G, R>(&self, guild_id: G, role_id: R) -> Option<Role> where G: Into<GuildId>, R: Into<RoleId> { self.guilds @@ -435,7 +435,7 @@ impl Cache { /// The only advantage of this method is that you can pass in anything that /// is indirectly a [`UserId`]. /// - /// [`UserId`]: ../../model/struct.UserId.html + /// [`UserId`]: ../model/struct.UserId.html /// [`users`]: #structfield.users #[inline] pub fn user<U: Into<UserId>>(&self, user_id: U) -> Option<Arc<RwLock<User>>> { diff --git a/src/client/context.rs b/src/client/context.rs index 27e5ab9..22216b1 100644 --- a/src/client/context.rs +++ b/src/client/context.rs @@ -1,18 +1,19 @@ use std::sync::{Arc, Mutex}; -use super::gateway::Shard; -use super::rest; use typemap::ShareMap; -use ::utils::builder::EditProfile; +use ::gateway::Shard; +use ::http; use ::internal::prelude::*; use ::model::*; #[cfg(feature="cache")] use super::CACHE; +#[cfg(feature="builder")] +use ::builder::EditProfile; /// The context is a general utility struct provided on event dispatches, which /// helps with dealing with the current "context" of the event dispatch. /// The context also acts as a general high-level interface over the associated -/// [`Shard`] which received the event, or the low-level [`rest`] module. +/// [`Shard`] which received the event, or the low-level [`http`] module. /// /// The context contains "shortcuts", like for interacting with the shard. /// Methods like [`set_game`] will unlock the shard and perform an update for @@ -21,8 +22,8 @@ use super::CACHE; /// A context will only live for the event it was dispatched for. After the /// event handler finished, it is destroyed and will not be re-used. /// -/// [`Shard`]: gateway/struct.Shard.html -/// [`rest`]: rest/index.html +/// [`Shard`]: ../gateway/struct.Shard.html +/// [`http`]: ../http/index.html /// [`set_game`]: #method.set_game #[derive(Clone)] pub struct Context { @@ -76,6 +77,7 @@ impl Context { /// ```rust,ignore /// context.edit_profile(|p| p.username("Hakase")); /// ``` + #[cfg(feature="builder")] pub fn edit_profile<F: FnOnce(EditProfile) -> EditProfile>(&self, f: F) -> Result<CurrentUser> { let mut map = Map::new(); @@ -88,7 +90,7 @@ impl Context { map.insert("email".to_owned(), Value::String(email.clone())); } } else { - let user = rest::get_current_user()?; + let user = http::get_current_user()?; map.insert("username".to_owned(), Value::String(user.name.clone())); @@ -99,7 +101,7 @@ impl Context { let edited = f(EditProfile(map)).0; - rest::edit_profile(&edited) + http::edit_profile(&edited) } /// Sets the current user as being [`Online`]. This maintains the current diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 56b5f6e..648cea7 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -2,8 +2,8 @@ use std::sync::{Arc, Mutex, RwLock}; use std::thread; use super::event_store::EventStore; use super::Context; -use super::gateway::Shard; use typemap::ShareMap; +use ::gateway::Shard; use ::model::event::Event; use ::model::{ChannelId, Message}; diff --git a/src/client/error.rs b/src/client/error.rs index a3df57c..a08d15b 100644 --- a/src/client/error.rs +++ b/src/client/error.rs @@ -1,152 +1,39 @@ -use hyper::status::StatusCode; -use ::constants::ErrorCode; -use ::model::{ChannelType, Permissions}; +use std::error::Error as StdError; +use std::fmt::{Display, Formatter, Result as FmtResult}; -/// An error returned from the [`Client`] or the [`Context`], or model instance. +/// An error returned from the [`Client`]. /// /// This is always wrapped within the library's generic [`Error::Client`] /// variant. /// -/// # Examples -/// -/// Matching an [`Error`] with this variant would look something like the -/// following for the [`GuildId::ban`] method, which in this example is used to -/// re-ban all members with an odd discriminator: -/// -/// ```rust,no_run -/// use serenity::client::{Client, ClientError}; -/// use serenity::Error; -/// use std::env; -/// -/// let token = env::var("DISCORD_BOT_TOKEN").unwrap(); -/// let mut client = Client::login(&token); -/// -/// client.on_member_unban(|context, guild_id, user| { -/// // If the user has an even discriminator, don't re-ban them. -/// if user.discriminator % 2 == 0 { -/// return; -/// } -/// -/// match guild_id.ban(user, 8) { -/// Ok(()) => { -/// // Ban successful. -/// }, -/// Err(Error::Client(ClientError::DeleteMessageDaysAmount(amount))) => { -/// println!("Failed deleting {} days' worth of messages", amount); -/// }, -/// Err(why) => { -/// println!("Unexpected error: {:?}", why); -/// }, -/// } -/// }); -/// ``` -/// /// [`Client`]: struct.Client.html -/// [`Context`]: struct.Context.html /// [`Error`]: ../enum.Error.html /// [`Error::Client`]: ../enum.Error.html#variant.Client /// [`GuildId::ban`]: ../model/struct.GuildId.html#method.ban #[allow(enum_variant_names)] #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum Error { - /// When attempting to delete below or above the minimum and maximum allowed - /// number of messages. - BulkDeleteAmount, - /// When attempting to delete a number of days' worth of messages that is - /// not allowed. - DeleteMessageDaysAmount(u8), - /// Indicates that the textual content of an embed exceeds the maximum - /// length. - EmbedTooLarge(u64), - /// When there is an error from Discord for a specific action, such as - /// [`ErrorCode::EditByOtherAuthor`]. This is a friendlier representation of - /// the numerical error codes Discord provides. - /// - /// [`ErrorCode::EditByOtherAuthor`]: rest/enum.ErrorCode.html#variant.EditByOtherAuthor - ErrorCode(ErrorCode), - /// When there was an error retrieving the gateway URI from the REST API. - Gateway, - /// An indication that a [guild][`Guild`] could not be found by - /// [Id][`GuildId`] in the [`Cache`]. - /// - /// [`Guild`]: ../model/struct.Guild.html - /// [`GuildId`]: ../model/struct.GuildId.html - /// [`Cache`]: ../ext/cache/struct.Cache.html - GuildNotFound, - /// An indicator that an unknown opcode was received from the gateway. - InvalidOpCode, - /// Indicates that you do not have the required permissions to perform an - /// operation. - /// - /// The provided [`Permission`]s is the set of required permissions - /// required. - /// - /// [`Permission`]: ../model/permissions/struct.Permissions.html - InvalidPermissions(Permissions), - /// An indicator that the shard data received from the gateway is invalid. - InvalidShards, /// When the token provided is invalid. This is returned when validating a /// token through the [`validate_token`] function. /// /// [`validate_token`]: fn.validate_token.html InvalidToken, - /// An indicator that the [current user] can not perform an action. - /// - /// [current user]: ../model/struct.CurrentUser.html - InvalidUser, - /// An indicator that an item is missing from the [`Cache`], and the action - /// can not be continued. - /// - /// [`Cache`]: ../ext/cache/struct.Cache.html - ItemMissing, - /// Indicates that a [`Message`]s content was too long and will not - /// successfully send, as the length is over 2000 codepoints, or 4000 bytes. - /// - /// The number of bytes larger than the limit is provided. - /// - /// [`Message`]: ../model/struct.Message.html - MessageTooLong(u64), - /// When attempting to use a [`Context`] helper method which requires a - /// contextual [`ChannelId`], but the current context is not appropriate for - /// the action. - /// - /// [`ChannelId`]: ../model/struct.ChannelId.html - /// [`Context`]: struct.Context.html - NoChannelId, - /// When the decoding of a ratelimit header could not be properly decoded - /// into an `i64`. - RateLimitI64, - /// When the decoding of a ratelimit header could not be properly decoded - /// from UTF-8. - RateLimitUtf8, - /// When attempting to find a required record from the Cache could not be - /// found. This is required in methods such as [`Context::edit_role`]. - /// - /// [`Context::edit_role`]: struct.Context.html#method.edit_role - RecordNotFound, /// When a shard has completely failed to reboot after resume and/or /// reconnect attempts. ShardBootFailure, - /// When the shard being retrieved from within the Client could not be - /// found after being inserted into the Client's internal vector of - /// [`Shard`]s. - /// - /// This can be returned from one of the options for starting one or - /// multiple shards. - /// - /// **This should never be received.** - /// - /// [`Shard`]: gateway/struct.Shard.html - ShardUnknown, - /// When a function such as [`Context::edit_channel`] did not expect the - /// received [`ChannelType`]. - /// - /// [`ChannelType`]: ../model/enum.ChannelType.html - /// [`Context::edit_channel`]: struct.Context.html#method.edit_channel - UnexpectedChannelType(ChannelType), - /// When a status code was unexpectedly received for a request's status. - InvalidRequest(StatusCode), - /// When a status is received, but the verification to ensure the response - /// is valid does not recognize the status. - UnknownStatus(u16), +} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + f.write_str(self.description()) + } +} + +impl StdError for Error { + fn description(&self) -> &str { + match *self { + Error::InvalidToken => "The provided token was invalid", + Error::ShardBootFailure => "Failed to (re-)boot a shard", + } + } } diff --git a/src/client/mod.rs b/src/client/mod.rs index d40792b..1ba555a 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -1,15 +1,15 @@ //! The Client contains information about a single bot or user's token, as well //! as event handlers. Dispatching events to configured handlers and starting //! the shards' connections are handled directly via the client. In addition, -//! the `rest` module and `Cache` are also automatically handled by the +//! the `http` module and `Cache` are also automatically handled by the //! Client module for you. //! //! A [`Context`] is provided for every handler. The context is a method of //! accessing the lower-level HTTP functions relevant to the contextual channel. //! -//! The `rest` module is the lower-level method of interacting with the Discord +//! The `http` module is the lower-level method of interacting with the Discord //! REST API. Realistically, there should be little reason to use this yourself, -//! as the Context will do this for you. A possible use case of using the `rest` +//! as the Context will do this for you. A possible use case of using the `http` //! module is if you do not have a Cache, for purposes such as low memory //! requirements. //! @@ -20,9 +20,6 @@ //! [Client examples]: struct.Client.html#examples #![allow(zero_ptr)] -pub mod gateway; -pub mod rest; - mod context; mod dispatch; mod error; @@ -31,66 +28,32 @@ mod event_store; pub use self::context::Context; pub use self::error::Error as ClientError; +// Note: the following re-exports are here for backwards compatibility +pub use ::gateway; +pub use ::http as rest; + +#[cfg(feature="cache")] +pub use ::CACHE; + use self::dispatch::dispatch; use self::event_store::EventStore; -use self::gateway::Shard; use std::collections::HashMap; use std::sync::{Arc, Mutex, RwLock}; use std::time::Duration; use std::{mem, thread}; +use super::gateway::Shard; use typemap::ShareMap; use websocket::client::Receiver; use websocket::result::WebSocketError; use websocket::stream::WebSocketStream; +use ::http; use ::internal::prelude::*; use ::internal::ws_impl::ReceiverExt; use ::model::event::*; use ::model::*; #[cfg(feature="framework")] -use ::ext::framework::Framework; - -#[cfg(feature="cache")] -use ::ext::cache::Cache; - -#[cfg(feature="cache")] -lazy_static! { - /// A mutable and lazily-initialized static binding. It can be accessed - /// across any function and in any context. - /// - /// This [`Cache`] instance is updated for every event received, so you do - /// not need to maintain your own cache. - /// - /// See the [cache module documentation] for more details. - /// - /// The Cache itself is wrapped within an `RwLock`, which allows for - /// multiple readers or at most one writer at a time across threads. This - /// means that you may have multiple commands reading from the Cache - /// concurrently. - /// - /// # Examples - /// - /// Retrieve the [current user][`CurrentUser`]'s Id, by opening a Read - /// guard: - /// - /// ```rust,ignore - /// use serenity::client::CACHE; - /// - /// println!("{}", CACHE.read().unwrap().user.id); - /// ``` - /// - /// By `unwrap()`ing, the thread managing an event dispatch will be blocked - /// until the guard can be opened. - /// - /// If you do not want to block the current thread, you may instead use - /// `RwLock::try_read`. Refer to `RwLock`'s documentation in the stdlib for - /// more information. - /// - /// [`CurrentUser`]: ../model/struct.CurrentUser.html - /// [`Cache`]: ../ext/cache/struct.Cache.html - /// [cache module documentation]: ../ext/cache/index.html - pub static ref CACHE: RwLock<Cache> = RwLock::new(Cache::default()); -} +use ::framework::Framework; /// The Client is the way to "login" and be able to start sending authenticated /// requests over the REST API, as well as initializing a WebSocket connection @@ -192,7 +155,7 @@ impl Client { /// information on usage. /// /// [`on_message`]: #method.on_message - /// [framework docs]: ../ext/framework/index.html + /// [framework docs]: ../framework/index.html #[cfg(feature="framework")] pub fn with_framework<F>(&mut self, f: F) where F: FnOnce(Framework) -> Framework + Send + Sync + 'static { @@ -213,7 +176,7 @@ impl Client { /// /// [gateway docs]: gateway/index.html#sharding pub fn start(&mut self) -> Result<()> { - self.start_connection(None, rest::get_gateway()?.url) + self.start_connection(None, http::get_gateway()?.url) } /// Establish the connection(s) and start listening for events. @@ -230,7 +193,7 @@ impl Client { /// /// [gateway docs]: gateway/index.html#sharding pub fn start_autosharded(&mut self) -> Result<()> { - let mut res = rest::get_bot_gateway()?; + let mut res = http::get_bot_gateway()?; let x = res.shards as u64 - 1; let y = res.shards as u64; @@ -255,7 +218,7 @@ impl Client { /// /// [gateway docs]: gateway/index.html#sharding pub fn start_shard(&mut self, shard: u64, shards: u64) -> Result<()> { - self.start_connection(Some([shard, shard, shards]), rest::get_gateway()?.url) + self.start_connection(Some([shard, shard, shards]), http::get_gateway()?.url) } /// Establish sharded connections and start listening for events. @@ -274,7 +237,7 @@ impl Client { /// [`start_shard_range`]: #method.start_shards /// [Gateway docs]: gateway/index.html#sharding pub fn start_shards(&mut self, total_shards: u64) -> Result<()> { - self.start_connection(Some([0, total_shards - 1, total_shards]), rest::get_gateway()?.url) + self.start_connection(Some([0, total_shards - 1, total_shards]), http::get_gateway()?.url) } /// Establish a range of sharded connections and start listening for events. @@ -308,7 +271,7 @@ impl Client { /// [`start_shards`]: #method.start_shards /// [Gateway docs]: gateway/index.html#sharding pub fn start_shard_range(&mut self, range: [u64; 2], total_shards: u64) -> Result<()> { - self.start_connection(Some([range[0], range[1], total_shards]), rest::get_gateway()?.url) + self.start_connection(Some([range[0], range[1], total_shards]), http::get_gateway()?.url) } /// Attaches a handler for when a [`ChannelCreate`] is received. @@ -665,7 +628,7 @@ impl Client { // This also acts as a form of check to ensure the token is correct. #[cfg(feature="framework")] { - let user = rest::get_current_user()?; + let user = http::get_current_user()?; self.framework.lock() .unwrap() @@ -778,7 +741,7 @@ impl Client { /// /// [`GuildDelete`]: ../model/event/enum.Event.html#variant.GuildDelete /// [`Role`]: ../model/struct.Role.html - /// [`Cache`]: ../ext/cache/struct.Cache.html + /// [`Cache`]: ../cache/struct.Cache.html pub fn on_guild_delete<F>(&mut self, handler: F) where F: Fn(Context, PartialGuild, Option<Arc<RwLock<Guild>>>) + Send + Sync + 'static { self.event_store.write() @@ -825,7 +788,7 @@ impl Client { /// it did not exist in the [`Cache`] before the update. /// /// [`GuildRoleUpdate`]: ../model/event/enum.Event.html#variant.GuildRoleUpdate - /// [`Cache`]: ../ext/cache/struct.Cache.html + /// [`Cache`]: ../cache/struct.Cache.html pub fn on_guild_role_update<F>(&mut self, handler: F) where F: Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static { self.event_store.write() @@ -872,7 +835,7 @@ impl Client { /// /// [`GuildDelete`]: ../model/event/enum.Event.html#variant.GuildDelete /// [`Role`]: ../model/struct.Role.html - /// [`Cache`]: ../ext/cache/struct.Cache.html + /// [`Cache`]: ../cache/struct.Cache.html pub fn on_guild_delete<F>(&mut self, handler: F) where F: Fn(Context, PartialGuild) + Send + Sync + 'static { self.event_store.write() @@ -916,7 +879,7 @@ impl Client { /// Attaches a handler for when a [`GuildRoleUpdate`] is received. /// /// [`GuildRoleUpdate`]: ../model/event/enum.Event.html#variant.GuildRoleUpdate - /// [`Cache`]: ../ext/cache/struct.Cache.html + /// [`Cache`]: ../cache/struct.Cache.html pub fn on_guild_role_update<F>(&mut self, handler: F) where F: Fn(Context, GuildId, Role) + Send + Sync + 'static { self.event_store.write() @@ -985,7 +948,7 @@ fn boot_shard(info: &BootInfo) -> Result<(Shard, ReadyEvent, Receiver<WebSocketS // // If doing so fails, count this as a boot attempt. if attempt_number > 3 { - match rest::get_gateway() { + match http::get_gateway() { Ok(g) => *info.gateway_url.lock().unwrap() = g.url, Err(why) => { warn!("Failed to retrieve gateway URL: {:?}", why); @@ -1137,7 +1100,7 @@ fn handle_shard(info: &mut MonitorInfo) { } fn login(token: String) -> Client { - rest::set_token(&token); + http::set_token(&token); feature_framework! {{ Client { diff --git a/src/constants.rs b/src/constants.rs index 5c98527..148b348 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,3 +1,5 @@ +//! A set of constants used by the library. + /// The maximum length of the textual size of an embed. pub const EMBED_MAX_LENGTH: u16 = 4000; /// The gateway version used by the library. The gateway URI is retrieved via @@ -37,53 +39,6 @@ pub static JOIN_MESSAGES: &'static [&'static str] = &[ "$user just showed up. Hold my beer." ]; - -#[allow(dead_code)] -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub enum ErrorCode { - BotsCannotUse, - CannotSendEmptyMessage, - CannotSendMessagesInVoice, - CannotSendMessagesToUser, - ChannelVerificationTooHigh, - EditByOtherAuthor, - EmbedDisabled, - InvalidAccountType, - InvalidAuthToken, - InvalidBulkDeleteCount, - InvalidDMChannelAction, - InvalidOauthState, - InvalidPinChannel, - MaxFriendsReached, - MaxGuildsReached, - MaxPinsReached, - MaxRolesReached, - MissingAccess, - MissingPermissions, - NoteTooLong, - Oauth2ApplicationLacksBot, - Oauth2ApplicationLimitReached, - OnlyBotsCanUse, - ReactionBlocked, - SearchIndexUnavailable, - TooManyReactions, - Unauthorized, - UnknownAccount, - UnknownApplication, - UnknownChannel, - UnknownGuild, - UnknownEmoji, - UnknownIntegration, - UnknownInvite, - UnknownMember, - UnknownMessage, - UnknownOverwrite, - UnknownProvider, - UnknownRole, - UnknownToken, - UnknownUser, -} - enum_number!( /// Enum to map gateway opcodes. OpCode { diff --git a/src/error.rs b/src/error.rs index d6fbd63..7795db5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,17 +1,25 @@ -use hyper::Error as HyperError; use serde_json::Error as JsonError; -use serde_json::Value; use std::io::Error as IoError; use std::error::Error as StdError; use std::fmt::{self, Display, Error as FormatError}; use std::num::ParseIntError; -use websocket::result::WebSocketError; -use ::client::gateway::GatewayError; -use ::client::ClientError; +use ::internal::prelude::*; +use ::model::ModelError; + +#[cfg(feature="hyper")] +use hyper::Error as HyperError; #[cfg(feature="voice")] use opus::Error as OpusError; +#[cfg(feature="websocket")] +use websocket::result::WebSocketError; +#[cfg(feature="client")] +use ::client::ClientError; +#[cfg(feature="gateway")] +use ::gateway::GatewayError; +#[cfg(feature="http")] +use ::http::HttpError; #[cfg(feature="voice")] -use ::ext::voice::VoiceError; +use ::voice::VoiceError; /// The common result type between most library functions. /// @@ -21,7 +29,7 @@ use ::ext::voice::VoiceError; /// implied, and a "simpler" result is used. /// /// [`Error`]: enum.Error.html -pub type Result<T> = ::std::result::Result<T, Error>; +pub type Result<T> = StdResult<T, Error>; /// A common error enum returned by most of the library's functionality within a /// custom [`Result`]. @@ -33,29 +41,22 @@ pub type Result<T> = ::std::result::Result<T, Error>; /// [`Client`]: #variant.Client /// [`ClientError`]: client/enum.ClientError.html /// [`Gateway`]: #variant.Gateway -/// [`GatewayError`]: client/gateway/enum.GatewayError.html +/// [`GatewayError`]: gateway/enum.GatewayError.html /// [`Result`]: type.Result.html #[derive(Debug)] pub enum Error { - /// A [rest] or [client] error. - /// - /// [client]: client/index.html - /// [rest]: client/rest/index.html - Client(ClientError), - /// An error with the WebSocket [`Gateway`]. - /// - /// [`Gateway`]: client/gateway/index.html - Gateway(GatewayError), /// An error while decoding a payload. Decode(&'static str, Value), /// There was an error with a format. Format(FormatError), - /// An error from the `hyper` crate. - Hyper(HyperError), /// An `std::io` error. Io(IoError), /// An error from the `serde_json` crate. Json(JsonError), + /// An error from the [`model`] module. + /// + /// [`model`]: model/index.html + Model(ModelError), /// An error occurred while parsing an integer. Num(ParseIntError), /// Some other error. This is only used for "Expected value <TYPE>" errors, @@ -66,14 +67,31 @@ pub enum Error { Other(&'static str), /// An error from the `url` crate. Url(String), + /// A [client] error. + /// + /// [client]: client/index.html + #[cfg(feature="client")] + Client(ClientError), + /// An error from the `gateway` module. + #[cfg(feature="gateway")] + Gateway(GatewayError), + /// An error from the [`http`] module. + /// + /// [`http`]: http/index.html + #[cfg(feature="http")] + Http(HttpError), + /// An error from the `hyper` crate. + #[cfg(feature="hyper")] + Hyper(HyperError), /// An error from the `rust-websocket` crate. + #[cfg(feature="gateway")] WebSocket(WebSocketError), /// An error from the `opus` crate. #[cfg(feature="voice")] Opus(OpusError), /// Indicating an error within the [voice module]. /// - /// [voice module]: ext/voice/index.html + /// [voice module]: voice/index.html #[cfg(feature="voice")] Voice(VoiceError), } @@ -84,18 +102,26 @@ impl From<FormatError> for Error { } } -impl From<IoError> for Error { - fn from(e: IoError) -> Error { - Error::Io(e) +#[cfg(feature="gateway")] +impl From<GatewayError> for Error { + fn from(e: GatewayError) -> Error { + Error::Gateway(e) } } +#[cfg(feature="hyper")] impl From<HyperError> for Error { fn from(e: HyperError) -> Error { Error::Hyper(e) } } +impl From<IoError> for Error { + fn from(e: IoError) -> Error { + Error::Io(e) + } +} + impl From<JsonError> for Error { fn from(e: JsonError) -> Error { Error::Json(e) @@ -115,6 +141,7 @@ impl From<OpusError> for Error { } } +#[cfg(feature="gateway")] impl From<WebSocketError> for Error { fn from(e: WebSocketError) -> Error { Error::WebSocket(e) @@ -124,9 +151,11 @@ impl From<WebSocketError> for Error { impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Error::Hyper(ref inner) => inner.fmt(f), Error::Io(ref inner) => inner.fmt(f), Error::Json(ref inner) => inner.fmt(f), + #[cfg(feature="http")] + Error::Hyper(ref inner) => inner.fmt(f), + #[cfg(feature="gateway")] Error::WebSocket(ref inner) => inner.fmt(f), #[cfg(feature="voice")] Error::Opus(ref inner) => inner.fmt(f), @@ -138,29 +167,38 @@ impl Display for Error { impl StdError for Error { fn description(&self) -> &str { match *self { - Error::Client(_) => "Client refused a request", Error::Decode(msg, _) | Error::Other(msg) => msg, Error::Format(ref inner) => inner.description(), - Error::Gateway(ref _inner) => "Gateway error", - Error::Hyper(ref inner) => inner.description(), Error::Io(ref inner) => inner.description(), Error::Json(ref inner) => inner.description(), + Error::Model(ref inner) => inner.description(), Error::Num(ref inner) => inner.description(), Error::Url(ref inner) => inner, - Error::WebSocket(ref inner) => inner.description(), + #[cfg(feature="client")] + Error::Client(ref inner) => inner.description(), + #[cfg(feature="gateway")] + Error::Gateway(ref inner) => inner.description(), + #[cfg(feature="http")] + Error::Http(ref inner) => inner.description(), + #[cfg(feature="http")] + Error::Hyper(ref inner) => inner.description(), #[cfg(feature="voice")] Error::Opus(ref inner) => inner.description(), #[cfg(feature="voice")] Error::Voice(_) => "Voice error", + #[cfg(feature="gateway")] + Error::WebSocket(ref inner) => inner.description(), } } fn cause(&self) -> Option<&StdError> { match *self { + #[cfg(feature="http")] Error::Hyper(ref inner) => Some(inner), Error::Json(ref inner) => Some(inner), - Error::WebSocket(ref inner) => Some(inner), Error::Io(ref inner) => Some(inner), + #[cfg(feature="gateway")] + Error::WebSocket(ref inner) => Some(inner), _ => None, } } diff --git a/src/ext/mod.rs b/src/ext.rs index 6254539..291ef9d 100644 --- a/src/ext/mod.rs +++ b/src/ext.rs @@ -9,10 +9,13 @@ //! enabled (enabled by default), the cache requires the `cache` feature to be //! enabled (enabled by default), and voice support requires the `voice` feature //! to be enabled (disabled by default). +//! +//! **Note**: This module exists for backwards compatibility purposes. Instead, +//! prefer to use the root modules directly. #[cfg(feature="cache")] -pub mod cache; +pub use super::cache; #[cfg(feature="framework")] -pub mod framework; +pub use super::framework; #[cfg(feature="voice")] -pub mod voice; +pub use super::voice; diff --git a/src/ext/framework/buckets.rs b/src/framework/buckets.rs index 02cd658..02cd658 100644 --- a/src/ext/framework/buckets.rs +++ b/src/framework/buckets.rs diff --git a/src/ext/framework/command.rs b/src/framework/command.rs index 5f43284..5f43284 100644 --- a/src/ext/framework/command.rs +++ b/src/framework/command.rs diff --git a/src/ext/framework/configuration.rs b/src/framework/configuration.rs index 4f73359..c104e1e 100644 --- a/src/ext/framework/configuration.rs +++ b/src/framework/configuration.rs @@ -1,7 +1,8 @@ use std::collections::HashSet; use std::default::Default; use super::command::PrefixCheck; -use ::client::{Context, rest}; +use ::client::Context; +use ::http; use ::model::{GuildId, UserId}; /// The configuration to use for a [`Framework`] associated with a [`Client`] @@ -201,7 +202,7 @@ impl Configuration { return self; } - if let Ok(current_user) = rest::get_current_user() { + if let Ok(current_user) = http::get_current_user() { self.on_mention = Some(vec![ format!("<@{}>", current_user.id), // Regular mention format!("<@!{}>", current_user.id), // Nickname mention diff --git a/src/ext/framework/create_command.rs b/src/framework/create_command.rs index 512e82c..512e82c 100644 --- a/src/ext/framework/create_command.rs +++ b/src/framework/create_command.rs diff --git a/src/ext/framework/create_group.rs b/src/framework/create_group.rs index 03fc33e..03fc33e 100644 --- a/src/ext/framework/create_group.rs +++ b/src/framework/create_group.rs diff --git a/src/ext/framework/help_commands.rs b/src/framework/help_commands.rs index 1f38bd5..1f38bd5 100644 --- a/src/ext/framework/help_commands.rs +++ b/src/framework/help_commands.rs diff --git a/src/ext/framework/mod.rs b/src/framework/mod.rs index cde10b2..99e7c44 100644 --- a/src/ext/framework/mod.rs +++ b/src/framework/mod.rs @@ -52,7 +52,7 @@ //! }); //! ``` //! -//! [`Client::with_framework`]: ../../client/struct.Client.html#method.with_framework +//! [`Client::with_framework`]: ../client/struct.Client.html#method.with_framework pub mod help_commands; @@ -113,7 +113,7 @@ use ::model::Channel; /// }); /// ``` /// -/// [`Framework`]: ext/framework/index.html +/// [`Framework`]: framework/index.html #[macro_export] macro_rules! command { ($fname:ident($c:ident) $b:block) => { @@ -235,8 +235,8 @@ pub struct Framework { /// framework check if a [`Event::MessageCreate`] should be processed by /// itself. /// - /// [`Client::on_message`]: ../../client/struct.Client.html#method.on_message - /// [`Event::MessageCreate`]: ../../model/event/enum.Event.html#variant.MessageCreate + /// [`Client::on_message`]: ../client/struct.Client.html#method.on_message + /// [`Event::MessageCreate`]: ../model/event/enum.Event.html#variant.MessageCreate pub initialized: bool, user_info: (u64, bool), } @@ -263,7 +263,7 @@ impl Framework { /// .prefix("~"))); /// ``` /// - /// [`Client`]: ../../client/struct.Client.html + /// [`Client`]: ../client/struct.Client.html /// [`Configuration::default`]: struct.Configuration.html#method.default /// [`depth`]: struct.Configuration.html#method.depth /// [`prefix`]: struct.Configuration.html#method.prefix diff --git a/src/client/gateway/error.rs b/src/gateway/error.rs index 121de71..57fa1cf 100644 --- a/src/client/gateway/error.rs +++ b/src/gateway/error.rs @@ -1,3 +1,4 @@ +use std::error::Error as StdError; use std::fmt::{self, Display}; /// An error that occurred while attempting to deal with the gateway. @@ -6,12 +7,16 @@ use std::fmt::{self, Display}; /// you manually handle these. #[derive(Clone, Debug)] pub enum Error { + /// There was an error building a URL. + BuildingUrl, /// The connection closed, potentially uncleanly. Closed(Option<u16>, String), /// Expected a Hello during a handshake ExpectedHello, /// Expected a Ready or an InvalidateSession InvalidHandshake, + /// An indicator that an unknown opcode was received from the gateway. + InvalidOpCode, /// When a session Id was expected (for resuming), but was not present. NoSessionId, /// Failed to reconnect after a number of attempts. @@ -20,14 +25,20 @@ pub enum Error { impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.description()) + } +} + +impl StdError for Error { + fn description(&self) -> &str { match *self { - Error::Closed(s, ref v) => { - f.write_str(&format!("Connection closed {:?}: {:?}", s, v)) - }, - Error::ExpectedHello => f.write_str("Expected Hello during handshake"), - Error::InvalidHandshake => f.write_str("Expected Ready or InvalidateSession"), - Error::NoSessionId => f.write_str("No Session Id present"), - Error::ReconnectFailure => f.write_str("Failed to Reconnect"), + Error::BuildingUrl => "Error building url", + Error::Closed(_, _) => "Connection closed", + Error::ExpectedHello => "Expected a Hello", + Error::InvalidHandshake => "Expected a valid Handshake", + Error::InvalidOpCode => "Invalid OpCode", + Error::NoSessionId => "No Session Id present when required", + Error::ReconnectFailure => "Failed to Reconnect", } } } diff --git a/src/client/gateway/mod.rs b/src/gateway/mod.rs index 38cdaa1..38cdaa1 100644 --- a/src/client/gateway/mod.rs +++ b/src/gateway/mod.rs diff --git a/src/client/gateway/prep.rs b/src/gateway/prep.rs index 5609749..f432691 100644 --- a/src/client/gateway/prep.rs +++ b/src/gateway/prep.rs @@ -7,7 +7,6 @@ use std::sync::mpsc::{ use std::sync::{Arc, Mutex}; use std::time::{Duration as StdDuration, Instant}; use std::{env, thread}; -use super::super::ClientError; use super::{GatewayError, GatewayStatus}; use time::{self, Duration}; use websocket::client::request::Url as RequestUrl; @@ -57,7 +56,7 @@ pub fn identify(token: &str, shard_info: Option<[u64; 2]>) -> Value { json!({ "op": OpCode::Identify.num(), "d": { - "compression": !cfg!(feature="debug"), + "compression": true, "large_threshold": LARGE_THRESHOLD, "shard": shard_info.unwrap_or([0, 1]), "token": token, @@ -73,7 +72,7 @@ pub fn identify(token: &str, shard_info: Option<[u64; 2]>) -> Value { pub fn build_gateway_url(base: &str) -> Result<RequestUrl> { RequestUrl::parse(&format!("{}?v={}", base, constants::GATEWAY_VERSION)) - .map_err(|_| Error::Client(ClientError::Gateway)) + .map_err(|_| Error::Gateway(GatewayError::BuildingUrl)) } pub fn keepalive(interval: u64, diff --git a/src/client/gateway/shard.rs b/src/gateway/shard.rs index a64ff2a..c9886c4 100644 --- a/src/client/gateway/shard.rs +++ b/src/gateway/shard.rs @@ -5,7 +5,6 @@ use std::sync::{Arc, Mutex}; use std::thread::{self, Builder as ThreadBuilder}; use std::time::{Duration as StdDuration, Instant}; use std::mem; -use super::super::rest; use super::{GatewayError, GatewayStatus, prep}; use time; use websocket::client::{Client as WsClient, Sender, Receiver}; @@ -14,6 +13,7 @@ use websocket::result::WebSocketError; use websocket::stream::WebSocketStream; use websocket::ws::sender::Sender as WsSender; use ::constants::OpCode; +use ::http; use ::internal::prelude::*; use ::internal::ws_impl::{ReceiverExt, SenderExt}; use ::model::event::{Event, GatewayEvent, ReadyEvent}; @@ -95,13 +95,13 @@ impl Shard { /// then listening for events: /// /// ```rust,ignore - /// use serenity::client::gateway::Shard; - /// use serenity::client::rest; + /// use serenity::gateway::Shard; + /// use serenity::http; /// use std::env; /// /// let token = env::var("DISCORD_BOT_TOKEN").expect("Token in environment"); /// // retrieve the gateway response, which contains the URL to connect to - /// let gateway = rest::get_gateway().expect("Valid gateway response").url; + /// let gateway = http::get_gateway().expect("Valid gateway response").url; /// let shard = Shard::new(&gateway, &token, None) /// .expect("Working shard"); /// @@ -517,7 +517,7 @@ impl Shard { /// /// **Note**: Requires the `cache` feature be enabled. /// - /// [`Cache`]: ../../ext/cache/struct.Cache.html + /// [`Cache`]: ../cache/struct.Cache.html #[cfg(feature="cache")] pub fn guilds_handled(&self) -> u16 { let cache = CACHE.read().unwrap(); @@ -560,7 +560,7 @@ impl Shard { // Take a few attempts at reconnecting. for i in 1u64..11u64 { - let gateway_url = rest::get_gateway()?.url; + let gateway_url = http::get_gateway()?.url; let shard = Shard::new(&gateway_url, &self.token, diff --git a/src/client/gateway/status.rs b/src/gateway/status.rs index f6e5ec2..f6e5ec2 100644 --- a/src/client/gateway/status.rs +++ b/src/gateway/status.rs diff --git a/src/http/error.rs b/src/http/error.rs new file mode 100644 index 0000000..8e68c44 --- /dev/null +++ b/src/http/error.rs @@ -0,0 +1,35 @@ +use hyper::status::StatusCode; +use std::error::Error as StdError; +use std::fmt::{Display, Formatter, Result as FmtResult}; + +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub enum Error { + /// When a status code was unexpectedly received for a request's status. + InvalidRequest(StatusCode), + /// When the decoding of a ratelimit header could not be properly decoded + /// into an `i64`. + RateLimitI64, + /// When the decoding of a ratelimit header could not be properly decoded + /// from UTF-8. + RateLimitUtf8, + /// When a status is received, but the verification to ensure the response + /// is valid does not recognize the status. + UnknownStatus(u16), +} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + f.write_str(self.description()) + } +} + +impl StdError for Error { + fn description(&self) -> &str { + match *self { + Error::InvalidRequest(_) => "Received an unexpected status code", + Error::RateLimitI64 => "Error decoding a header into an i64", + Error::RateLimitUtf8 => "Error decoding a header from UTF-8", + Error::UnknownStatus(_) => "Verification does not understand status", + } + } +} diff --git a/src/client/rest/mod.rs b/src/http/mod.rs index 3890a46..8c7f4c4 100644 --- a/src/client/rest/mod.rs +++ b/src/http/mod.rs @@ -26,6 +26,9 @@ pub mod ratelimiting; +mod error; + +pub use self::error::Error as HttpError; pub use hyper::status::{StatusClass, StatusCode}; use hyper::client::{ @@ -207,14 +210,14 @@ pub fn create_emoji(guild_id: u64, map: &Value) -> Result<Emoji> { /// /// use serde_json::builder::ObjectBuilder; /// use serde_json::Value; -/// use serenity::client::rest; +/// use serenity::http; /// /// let map = ObjectBuilder::new() /// .insert("name", "test") /// .insert("region", "us-west") /// .build(); /// -/// let _result = rest::create_guild(map); +/// let _result = http::create_guild(map); /// ``` /// /// [`Guild`]: ../../model/struct.Guild.html @@ -339,12 +342,12 @@ pub fn create_role(guild_id: u64, map: &JsonMap) -> Result<Role> { /// extern crate serenity; /// /// use serde_json::builder::ObjectBuilder; -/// use serenity::client::rest; +/// use serenity::http; /// /// let channel_id = 81384788765712384; /// let map = ObjectBuilder::new().insert("name", "test").build(); /// -/// let webhook = rest::create_webhook(channel_id, map).expect("Error creating"); +/// let webhook = http::create_webhook(channel_id, map).expect("Error creating"); /// ``` /// /// [`GuildChannel`]: ../../model/struct.GuildChannel.html @@ -428,13 +431,13 @@ pub fn delete_messages(channel_id: u64, map: &Value) -> Result<()> { /// # Examples /// /// ```rust,no_run -/// use serenity::client::rest; +/// use serenity::http; /// use serenity::model::{ChannelId, MessageId}; /// /// let channel_id = ChannelId(7); /// let message_id = MessageId(8); /// -/// let _ = rest::delete_message_reactions(channel_id.0, message_id.0) +/// let _ = http::delete_message_reactions(channel_id.0, message_id.0) /// .expect("Error deleting reactions"); /// ``` /// @@ -494,14 +497,14 @@ pub fn delete_role(guild_id: u64, role_id: u64) -> Result<()> { /// Deletes a webhook given its Id: /// /// ```rust,no_run -/// use serenity::client::{Client, rest}; +/// use serenity::{Client, http}; /// use std::env; /// /// // Due to the `delete_webhook` function requiring you to authenticate, you /// // must have set the token first. -/// rest::set_token(&env::var("DISCORD_TOKEN").unwrap()); +/// http::set_token(&env::var("DISCORD_TOKEN").unwrap()); /// -/// rest::delete_webhook(245037420704169985).expect("Error deleting webhook"); +/// http::delete_webhook(245037420704169985).expect("Error deleting webhook"); /// ``` /// /// [`Webhook`]: ../../model/struct.Webhook.html @@ -519,12 +522,12 @@ pub fn delete_webhook(webhook_id: u64) -> Result<()> { /// Deletes a webhook given its Id and unique token: /// /// ```rust,no_run -/// use serenity::client::rest; +/// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// -/// rest::delete_webhook_with_token(id, token).expect("Error deleting webhook"); +/// http::delete_webhook_with_token(id, token).expect("Error deleting webhook"); /// ``` /// /// [`Webhook`]: ../../model/struct.Webhook.html @@ -689,7 +692,7 @@ pub fn edit_role(guild_id: u64, role_id: u64, map: &JsonMap) -> Result<Role> { /// extern crate serenity; /// /// use serde_json::builder::ObjectBuilder; -/// use serenity::client::rest; +/// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; @@ -697,7 +700,7 @@ pub fn edit_role(guild_id: u64, role_id: u64, map: &JsonMap) -> Result<Role> { /// .expect("Error reading image"); /// let map = ObjectBuilder::new().insert("avatar", image).build(); /// -/// let edited = rest::edit_webhook_with_token(id, token, map) +/// let edited = http::edit_webhook_with_token(id, token, map) /// .expect("Error editing webhook"); /// ``` /// @@ -730,13 +733,13 @@ pub fn edit_webhook(webhook_id: u64, map: &Value) -> Result<Webhook> { /// extern crate serenity; /// /// use serde_json::builder::ObjectBuilder; -/// use serenity::client::rest; +/// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// let map = ObjectBuilder::new().insert("name", "new name").build(); /// -/// let edited = rest::edit_webhook_with_token(id, token, map) +/// let edited = http::edit_webhook_with_token(id, token, map) /// .expect("Error editing webhook"); /// ``` /// @@ -788,13 +791,13 @@ pub fn edit_webhook_with_token(webhook_id: u64, token: &str, map: &JsonMap) -> R /// extern crate serenity; /// /// use serde_json::builder::ObjectBuilder; -/// use serenity::client::rest; +/// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// let map = ObjectBuilder::new().insert("content", "test").build(); /// -/// let message = match rest::execute_webhook(id, token, map) { +/// let message = match http::execute_webhook(id, token, map) { /// Ok(message) => message, /// Err(why) => { /// println!("Error executing webhook: {:?}", why); @@ -887,11 +890,11 @@ pub fn get_channel_invites(channel_id: u64) -> Result<Vec<RichInvite>> { /// Retrieve all of the webhooks owned by a channel: /// /// ```rust,no_run -/// use serenity::client::rest; +/// use serenity::http; /// /// let channel_id = 81384788765712384; /// -/// let webhooks = rest::get_channel_webhooks(channel_id) +/// let webhooks = http::get_channel_webhooks(channel_id) /// .expect("Error getting channel webhooks"); /// ``` /// @@ -1080,11 +1083,11 @@ pub fn get_guild_roles(guild_id: u64) -> Result<Vec<Role>> { /// Retrieve all of the webhooks owned by a guild: /// /// ```rust,no_run -/// use serenity::client::rest; +/// use serenity::http; /// /// let guild_id = 81384788765712384; /// -/// let webhooks = rest::get_guild_webhooks(guild_id) +/// let webhooks = http::get_guild_webhooks(guild_id) /// .expect("Error getting guild webhooks"); /// ``` /// @@ -1109,7 +1112,7 @@ pub fn get_guild_webhooks(guild_id: u64) -> Result<Vec<Webhook>> { /// Get the first 10 guilds after a certain guild's Id: /// /// ```rust,no_run -/// use serenity::client::rest::{GuildPagination, get_guilds}; +/// use serenity::http::{GuildPagination, get_guilds}; /// use serenity::model::GuildId; /// /// let guild_id = GuildId(81384788765712384); @@ -1137,7 +1140,13 @@ pub fn get_guilds(target: &GuildPagination, limit: u64) -> Result<Vec<GuildInfo> /// Gets information about a specific invite. pub fn get_invite(code: &str, stats: bool) -> Result<Invite> { - let invite = ::utils::parse_invite(code); + let mut invite = code; + + #[cfg(feature="utils")] + { + invite = ::utils::parse_invite(invite); + } + let mut uri = format!("/invites/{}", invite); if stats { @@ -1288,10 +1297,10 @@ pub fn get_voice_regions() -> Result<Vec<VoiceRegion>> { /// Retrieve a webhook by Id: /// /// ```rust,no_run -/// use serenity::client::rest; +/// use serenity::http; /// /// let id = 245037420704169985; -/// let webhook = rest::get_webhook(id).expect("Error getting webhook"); +/// let webhook = http::get_webhook(id).expect("Error getting webhook"); /// ``` /// /// [`get_webhook_with_token`]: fn.get_webhook_with_token.html @@ -1310,12 +1319,12 @@ pub fn get_webhook(webhook_id: u64) -> Result<Webhook> { /// Retrieve a webhook by Id and its unique token: /// /// ```rust,no_run -/// use serenity::client::rest; +/// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// -/// let webhook = rest::get_webhook_with_token(id, token) +/// let webhook = http::get_webhook_with_token(id, token) /// .expect("Error getting webhook"); /// ``` pub fn get_webhook_with_token(webhook_id: u64, token: &str) -> Result<Webhook> { @@ -1479,7 +1488,7 @@ fn request<'a, F>(route: Route, f: F) -> Result<HyperResponse> if response.status.class() == StatusClass::Success { Ok(response) } else { - Err(Error::Client(ClientError::InvalidRequest(response.status))) + Err(Error::Http(HttpError::InvalidRequest(response.status))) } } @@ -1503,9 +1512,9 @@ fn verify(expected_status_code: u16, mut response: HyperResponse) -> Result<()> 204 => StatusCode::NoContent, 401 => StatusCode::Unauthorized, _ => { - let client_error = ClientError::UnknownStatus(expected_status_code); + let client_error = HttpError::UnknownStatus(expected_status_code); - return Err(Error::Client(client_error)); + return Err(Error::Http(client_error)); }, }; @@ -1520,7 +1529,7 @@ fn verify(expected_status_code: u16, mut response: HyperResponse) -> Result<()> debug!("Content: {}", s); - Err(Error::Client(ClientError::InvalidRequest(response.status))) + Err(Error::Http(HttpError::InvalidRequest(response.status))) } /// Representation of the method of a query to send for the [`get_guilds`] diff --git a/src/client/rest/ratelimiting.rs b/src/http/ratelimiting.rs index cb88476..2b467b5 100644 --- a/src/client/rest/ratelimiting.rs +++ b/src/http/ratelimiting.rs @@ -47,7 +47,7 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::Duration; use std::{str, thread}; -use super::LightMethod; +use super::{HttpError, LightMethod}; use time; use ::internal::prelude::*; @@ -78,7 +78,7 @@ lazy_static! { /// View the `reset` time of the route for `ChannelsId(7)`: /// /// ```rust,no_run - /// use serenity::client::rest::ratelimiting::{ROUTES, Route}; + /// use serenity::http::ratelimiting::{ROUTES, Route}; /// /// let routes = ROUTES.lock().unwrap(); /// @@ -94,9 +94,9 @@ lazy_static! { /// A representation of all routes registered within the library. These are safe /// and memory-efficient representations of each path that functions exist for -/// in the [`rest`] module. +/// in the [`http`] module. /// -/// [`rest`]: ../index.html +/// [`http`]: ../index.html #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum Route { /// Route for the `/channels/:channel_id` path. @@ -495,9 +495,9 @@ fn parse_header(headers: &Headers, header: &str) -> Result<Option<i64>> { Some(header) => match str::from_utf8(&header[0]) { Ok(v) => match v.parse::<i64>() { Ok(v) => Ok(Some(v)), - Err(_) => Err(Error::Client(ClientError::RateLimitI64)), + Err(_) => Err(Error::Http(HttpError::RateLimitI64)), }, - Err(_) => Err(Error::Client(ClientError::RateLimitUtf8)), + Err(_) => Err(Error::Http(HttpError::RateLimitUtf8)), }, None => Ok(None), } diff --git a/src/utils/macros.rs b/src/internal/macros.rs index 0a54d8f..0a54d8f 100644 --- a/src/utils/macros.rs +++ b/src/internal/macros.rs diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 591419b..f0b65d8 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -1,4 +1,9 @@ +#[macro_use] +pub mod macros; + pub mod prelude; + +#[cfg(feature="gateway")] pub mod ws_impl; #[cfg(feature="voice")] diff --git a/src/internal/prelude.rs b/src/internal/prelude.rs index 46cd337..e629322 100644 --- a/src/internal/prelude.rs +++ b/src/internal/prelude.rs @@ -8,5 +8,7 @@ pub type JsonMap = Map<String, Value>; pub use serde_json::{Map, Number, Value}; pub use std::result::Result as StdResult; -pub use ::client::ClientError; pub use ::error::{Error, Result}; + +#[cfg(feature="client")] +pub use ::client::ClientError; diff --git a/src/internal/ws_impl.rs b/src/internal/ws_impl.rs index abae6b9..5475a3e 100644 --- a/src/internal/ws_impl.rs +++ b/src/internal/ws_impl.rs @@ -5,7 +5,7 @@ use websocket::message::{Message as WsMessage, Type as WsType}; use websocket::stream::WebSocketStream; use websocket::ws::receiver::Receiver as WsReceiver; use websocket::ws::sender::Sender as WsSender; -use ::client::gateway::GatewayError; +use ::gateway::GatewayError; use ::internal::prelude::*; pub trait ReceiverExt { @@ -71,62 +71,128 @@ //! #[macro_use] extern crate serenity; //! ``` //! -//! [`Cache`]: ext/cache/struct.Cache.html +//! [`Cache`]: cache/struct.Cache.html //! [`Client::login`]: client/struct.Client.html#method.login //! [`Client::on_message`]: client/struct.Client.html#method.on_message //! [`Context`]: client/struct.Context.html //! [`Event`]: model/event/enum.Event.html //! [`Event::MessageCreate`]: model/event/enum.Event.html#variant.MessageCreate -//! [`Shard`]: client/gateway/struct.Shard.html +//! [`Shard`]: gateway/struct.Shard.html //! [`examples`]: https://github.com/zeyla/serenity/blob/master/examples -//! [cache docs]: ext/cache/index.html +//! [cache docs]: cache/index.html //! [client's module-level documentation]: client/index.html //! [docs]: https://discordapp.com/developers/docs/intro //! [examples]: https://github.com/zeyla/serenity/tree/master/examples -//! [gateway docs]: client/gateway/index.html +//! [gateway docs]: gateway/index.html #![allow(doc_markdown, inline_always, unknown_lints)] #![warn(enum_glob_use, if_not_else)] #[macro_use] extern crate bitflags; #[macro_use] -extern crate lazy_static; -#[macro_use] extern crate log; #[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_json; +#[cfg(feature="lazy_static")] +#[macro_use] +extern crate lazy_static; + extern crate base64; extern crate flate2; -extern crate hyper; -extern crate multipart; extern crate serde; extern crate time; -extern crate typemap; -extern crate websocket; #[cfg(feature="voice")] extern crate byteorder; +#[cfg(feature="hyper")] +extern crate hyper; +#[cfg(feature="http")] +extern crate multipart; #[cfg(feature="voice")] extern crate opus; #[cfg(feature="voice")] extern crate sodiumoxide; +#[cfg(feature="client")] +extern crate typemap; +#[cfg(feature="gateway")] +extern crate websocket; #[macro_use] -pub mod utils; +mod internal; -pub mod client; -pub mod ext; +pub mod constants; pub mod model; pub mod prelude; -#[macro_use] -mod internal; +#[cfg(feature="builder")] +pub mod builder; +#[cfg(feature="cache")] +pub mod cache; +#[cfg(feature="client")] +pub mod client; +#[cfg(any(feature="cache", feature="framework", feature="voice"))] +pub mod ext; +#[cfg(feature="framework")] +pub mod framework; +#[cfg(feature="gateway")] +pub mod gateway; +#[cfg(feature="http")] +pub mod http; +#[cfg(feature="utils")] +pub mod utils; +#[cfg(feature="voice")] +pub mod voice; -mod constants; mod error; -pub use client::Client; pub use error::{Error, Result}; + +#[cfg(feature="client")] +pub use client::Client; + +#[cfg(feature="cache")] +use cache::Cache; +#[cfg(feature="cache")] +use std::sync::RwLock; + +#[cfg(feature="cache")] +lazy_static! { + /// A mutable and lazily-initialized static binding. It can be accessed + /// across any function and in any context. + /// + /// This [`Cache`] instance is updated for every event received, so you do + /// not need to maintain your own cache. + /// + /// See the [cache module documentation] for more details. + /// + /// The Cache itself is wrapped within an `RwLock`, which allows for + /// multiple readers or at most one writer at a time across threads. This + /// means that you may have multiple commands reading from the Cache + /// concurrently. + /// + /// # Examples + /// + /// Retrieve the [current user][`CurrentUser`]'s Id, by opening a Read + /// guard: + /// + /// ```rust,ignore + /// use serenity::CACHE; + /// + /// println!("{}", CACHE.read().unwrap().user.id); + /// ``` + /// + /// By `unwrap()`ing, the thread managing an event dispatch will be blocked + /// until the guard can be opened. + /// + /// If you do not want to block the current thread, you may instead use + /// `RwLock::try_read`. Refer to `RwLock`'s documentation in the stdlib for + /// more information. + /// + /// [`CurrentUser`]: model/struct.CurrentUser.html + /// [`Cache`]: cache/struct.Cache.html + /// [cache module documentation]: cache/index.html + pub static ref CACHE: RwLock<Cache> = RwLock::new(Cache::default()); +} diff --git a/src/model/channel/attachment.rs b/src/model/channel/attachment.rs index 17e3076..b7f371b 100644 --- a/src/model/channel/attachment.rs +++ b/src/model/channel/attachment.rs @@ -1,3 +1,4 @@ +#[cfg(feature="model")] use hyper::Client as HyperClient; use std::io::Read; use ::internal::prelude::*; @@ -24,6 +25,7 @@ pub struct Attachment { pub width: Option<u64>, } +#[cfg(feature="model")] impl Attachment { /// If this attachment is an image, then a tuple of the width and height /// in pixels is returned. diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs index 46b00c6..3967dba 100644 --- a/src/model/channel/channel_id.rs +++ b/src/model/channel/channel_id.rs @@ -1,12 +1,15 @@ use std::fmt::{Display, Formatter, Result as FmtResult, Write as FmtWrite}; use std::io::Read; -use ::client::rest; use ::model::*; -use ::utils::builder::{CreateMessage, EditChannel, GetMessages}; +#[cfg(feature="model")] +use ::builder::{CreateMessage, EditChannel, GetMessages}; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; +#[cfg(feature="model")] +use ::http; +#[cfg(feature="model")] impl ChannelId { /// Broadcasts that the current user is typing to a channel for the next 5 /// seconds. @@ -30,7 +33,7 @@ impl ChannelId { /// [Send Messages]: permissions/constant.SEND_MESSAGES.html #[inline] pub fn broadcast_typing(&self) -> Result<()> { - rest::broadcast_typing(self.0) + http::broadcast_typing(self.0) } /// Creates a [permission overwrite][`PermissionOverwrite`] for either a @@ -60,7 +63,7 @@ impl ChannelId { "type": kind, }); - rest::create_permission(self.0, id, &map) + http::create_permission(self.0, id, &map) } /// React to a [`Message`] with a custom [`Emoji`] or unicode character. @@ -78,13 +81,13 @@ impl ChannelId { #[inline] pub fn create_reaction<M, R>(&self, message_id: M, reaction_type: R) -> Result<()> where M: Into<MessageId>, R: Into<ReactionType> { - rest::create_reaction(self.0, message_id.into().0, &reaction_type.into()) + http::create_reaction(self.0, message_id.into().0, &reaction_type.into()) } /// Deletes this channel, returning the channel on a successful deletion. #[inline] pub fn delete(&self) -> Result<Channel> { - rest::delete_channel(self.0) + http::delete_channel(self.0) } /// Deletes a [`Message`] given its Id. @@ -99,7 +102,7 @@ impl ChannelId { /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html #[inline] pub fn delete_message<M: Into<MessageId>>(&self, message_id: M) -> Result<()> { - rest::delete_message(self.0, message_id.into().0) + http::delete_message(self.0, message_id.into().0) } /// Deletes all messages by Ids from the given vector in the given channel. @@ -125,7 +128,7 @@ impl ChannelId { "messages": ids }); - rest::delete_messages(self.0, &map) + http::delete_messages(self.0, &map) } /// Deletes all permission overrides in the channel from a member or role. @@ -134,7 +137,7 @@ impl ChannelId { /// /// [Manage Channel]: permissions/constant.MANAGE_CHANNELS.html pub fn delete_permission(&self, permission_type: PermissionOverwriteType) -> Result<()> { - rest::delete_permission(self.0, match permission_type { + http::delete_permission(self.0, match permission_type { PermissionOverwriteType::Member(id) => id.0, PermissionOverwriteType::Role(id) => id.0, }) @@ -149,7 +152,7 @@ impl ChannelId { /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html pub fn delete_reaction<M, R>(&self, message_id: M, user_id: Option<UserId>, reaction_type: R) -> Result<()> where M: Into<MessageId>, R: Into<ReactionType> { - rest::delete_reaction(self.0, + http::delete_reaction(self.0, message_id.into().0, user_id.map(|uid| uid.0), &reaction_type.into()) @@ -172,17 +175,11 @@ impl ChannelId { /// channel_id.edit(|c| c.name("test").bitrate(64000)); /// ``` /// - /// # Errors - /// - /// Returns a [`ClientError::NoChannelId`] if the current context is not - /// related to a channel. - /// /// [`Channel`]: enum.Channel.html - /// [`ClientError::NoChannelId`]: ../client/enum.ClientError.html#variant.NoChannelId /// [Manage Channel]: permissions/constant.MANAGE_CHANNELS.html #[inline] pub fn edit<F: FnOnce(EditChannel) -> EditChannel>(&self, f: F) -> Result<GuildChannel> { - rest::edit_channel(self.0, &f(EditChannel::default()).0) + http::edit_channel(self.0, &f(EditChannel::default()).0) } /// Edits a [`Message`] in the channel given its Id. @@ -196,14 +193,14 @@ impl ChannelId { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the [`the limit`], containing the number of unicode code points /// over the limit. /// - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [`Message`]: struct.Message.html - /// [`the limit`]: ../utils/builder/struct.CreateMessage.html#method.content + /// [`the limit`]: ../builder/struct.CreateMessage.html#method.content pub fn edit_message<F, M>(&self, message_id: M, f: F) -> Result<Message> where F: FnOnce(CreateMessage) -> CreateMessage, M: Into<MessageId> { let map = f(CreateMessage::default()).0; @@ -211,12 +208,12 @@ impl ChannelId { if let Some(content) = map.get("content") { if let Value::String(ref content) = *content { if let Some(length_over) = Message::overflow_length(content) { - return Err(Error::Client(ClientError::MessageTooLong(length_over))); + return Err(Error::Model(ModelError::MessageTooLong(length_over))); } } } - rest::edit_message(self.0, message_id.into().0, &Value::Object(map)) + http::edit_message(self.0, message_id.into().0, &Value::Object(map)) } /// Search the cache for the channel with the Id. @@ -235,7 +232,7 @@ impl ChannelId { } } - rest::get_channel(self.0) + http::get_channel(self.0) } /// Gets all of the channel's invites. @@ -244,7 +241,7 @@ impl ChannelId { /// [Manage Channels]: permissions/constant.MANAGE_CHANNELS.html #[inline] pub fn invites(&self) -> Result<Vec<RichInvite>> { - rest::get_channel_invites(self.0) + http::get_channel_invites(self.0) } /// Gets a message from the channel. @@ -254,7 +251,7 @@ impl ChannelId { /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html #[inline] pub fn message<M: Into<MessageId>>(&self, message_id: M) -> Result<Message> { - rest::get_message(self.0, message_id.into().0) + http::get_message(self.0, message_id.into().0) .map(|mut msg| { msg.transform_content(); @@ -283,7 +280,7 @@ impl ChannelId { write!(query, "&before={}", before)?; } - rest::get_messages(self.0, &query) + http::get_messages(self.0, &query) .map(|msgs| msgs .into_iter() .map(|mut msg| { @@ -298,7 +295,7 @@ impl ChannelId { /// [`Message`]: struct.Message.html #[inline] pub fn pin<M: Into<MessageId>>(&self, message_id: M) -> Result<()> { - rest::pin_message(self.0, message_id.into().0) + http::pin_message(self.0, message_id.into().0) } /// Gets the list of [`Message`]s which are pinned to the channel. @@ -306,7 +303,7 @@ impl ChannelId { /// [`Message`]: struct.Message.html #[inline] pub fn pins(&self) -> Result<Vec<Message>> { - rest::get_pins(self.0) + http::get_pins(self.0) } /// Gets the list of [`User`]s who have reacted to a [`Message`] with a @@ -329,7 +326,7 @@ impl ChannelId { -> Result<Vec<User>> where M: Into<MessageId>, R: Into<ReactionType>, U: Into<UserId> { let limit = limit.map_or(50, |x| if x > 100 { 100 } else { x }); - rest::get_reaction_users(self.0, + http::get_reaction_users(self.0, message_id.into().0, &reaction_type.into(), limit, @@ -340,12 +337,12 @@ impl ChannelId { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// - /// [`ChannelId`]: ../model/struct.ChannelId.html - /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong + /// [`ChannelId`]: struct.ChannelId.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong #[inline] pub fn say(&self, content: &str) -> Result<Message> { self.send_message(|m| m.content(content)) @@ -382,11 +379,11 @@ impl ChannelId { /// # Errors /// /// If the content of the message is over the above limit, then a - /// [`ClientError::MessageTooLong`] will be returned, containing the number + /// [`ModelError::MessageTooLong`] will be returned, containing the number /// of unicode code points over the limit. /// - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage::content`]: ../utils/builder/struct.CreateMessage.html#method.content + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage::content`]: ../builder/struct.CreateMessage.html#method.content /// [`GuildChannel`]: struct.GuildChannel.html /// [Attach Files]: permissions/constant.ATTACH_FILES.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html @@ -397,14 +394,14 @@ impl ChannelId { if let Some(content) = map.get("content") { if let Value::String(ref content) = *content { if let Some(length_over) = Message::overflow_length(content) { - return Err(Error::Client(ClientError::MessageTooLong(length_over))); + return Err(Error::Model(ModelError::MessageTooLong(length_over))); } } } let _ = map.remove("embed"); - rest::send_file(self.0, file, filename, map) + http::send_file(self.0, file, filename, map) } /// Sends a message to the channel. @@ -418,13 +415,13 @@ impl ChannelId { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// /// [`Channel`]: enum.Channel.html - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html pub fn send_message<F>(&self, f: F) -> Result<Message> where F: FnOnce(CreateMessage) -> CreateMessage { @@ -433,7 +430,7 @@ impl ChannelId { Message::check_content_length(&map)?; Message::check_embed_length(&map)?; - rest::send_message(self.0, &Value::Object(map)) + http::send_message(self.0, &Value::Object(map)) } /// Unpins a [`Message`] in the channel given by its Id. @@ -444,7 +441,7 @@ impl ChannelId { /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html #[inline] pub fn unpin<M: Into<MessageId>>(&self, message_id: M) -> Result<()> { - rest::unpin_message(self.0, message_id.into().0) + http::unpin_message(self.0, message_id.into().0) } /// Retrieves the channel's webhooks. @@ -454,7 +451,7 @@ impl ChannelId { /// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html #[inline] pub fn webhooks(&self) -> Result<Vec<Webhook>> { - rest::get_channel_webhooks(self.0) + http::get_channel_webhooks(self.0) } /// Alias of [`invites`]. diff --git a/src/model/channel/embed.rs b/src/model/channel/embed.rs index b278622..9e35ea5 100644 --- a/src/model/channel/embed.rs +++ b/src/model/channel/embed.rs @@ -1,7 +1,11 @@ -use ::utils::builder::CreateEmbed; -use ::utils::Colour; use ::internal::prelude::*; +#[cfg(feature="utils")] +use ::utils::Colour; + +#[cfg(feature="model")] +use ::builder::CreateEmbed; + /// Represents a rich embed which allows using richer markdown, multiple fields /// and more. This was heavily inspired by [slack's attachments]. /// @@ -17,8 +21,13 @@ pub struct Embed { /// Information about the author of the embed. pub author: Option<EmbedAuthor>, /// The colour code of the embed. + #[cfg(feature="utils")] #[serde(default, rename="color")] pub colour: Colour, + /// The colour code of the embed. + #[cfg(not(feature="utils"))] + #[serde(default, rename="color")] + pub colour: u32, /// The description of the embed. /// /// The maximum value for this field is 2048 unicode codepoints. @@ -53,6 +62,7 @@ pub struct Embed { pub video: Option<EmbedVideo>, } +#[cfg(feature="model")] impl Embed { /// Creates a fake Embed, giving back a `serde_json` map. /// diff --git a/src/model/channel/group.rs b/src/model/channel/group.rs index bf87590..adafdc8 100644 --- a/src/model/channel/group.rs +++ b/src/model/channel/group.rs @@ -1,9 +1,12 @@ use std::borrow::Cow; use std::fmt::Write as FmtWrite; use std::io::Read; -use ::client::rest; use ::model::*; -use ::utils::builder::{CreateMessage, GetMessages}; + +#[cfg(feature="model")] +use ::builder::{CreateMessage, GetMessages}; +#[cfg(feature="model")] +use ::http; /// A group channel - potentially including other [`User`]s - separate from a /// [`Guild`]. @@ -30,16 +33,17 @@ pub struct Group { pub recipients: HashMap<UserId, Arc<RwLock<User>>>, } +#[cfg(feature="model")] impl Group { /// Adds the given user to the group. If the user is already in the group, /// then nothing is done. /// - /// Refer to [`rest::add_group_recipient`] for more information. + /// Refer to [`http::add_group_recipient`] for more information. /// /// **Note**: Groups have a limit of 10 recipients, including the current /// user. /// - /// [`rest::add_group_recipient`]: ../client/rest/fn.add_group_recipient.html + /// [`http::add_group_recipient`]: ../http/fn.add_group_recipient.html pub fn add_recipient<U: Into<UserId>>(&self, user: U) -> Result<()> { let user = user.into(); @@ -48,7 +52,7 @@ impl Group { return Ok(()); } - rest::add_group_recipient(self.channel_id.0, user.0) + http::add_group_recipient(self.channel_id.0, user.0) } /// Broadcasts that the current user is typing in the group. @@ -129,14 +133,14 @@ impl Group { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the [`the limit`], containing the number of unicode code points /// over the limit. /// - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [`Message`]: struct.Message.html - /// [`the limit`]: ../utils/builder/struct.CreateMessage.html#method.content + /// [`the limit`]: ../builder/struct.CreateMessage.html#method.content #[inline] pub fn edit_message<F, M>(&self, message_id: M, f: F) -> Result<Message> where F: FnOnce(CreateMessage) -> CreateMessage, M: Into<MessageId> { @@ -165,7 +169,7 @@ impl Group { /// Leaves the group. #[inline] pub fn leave(&self) -> Result<Group> { - rest::leave_group(self.channel_id.0) + http::leave_group(self.channel_id.0) } /// Gets a message from the channel. @@ -252,19 +256,19 @@ impl Group { return Ok(()); } - rest::remove_group_recipient(self.channel_id.0, user.0) + http::remove_group_recipient(self.channel_id.0, user.0) } /// Sends a message with just the given message content in the channel. /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// /// [`ChannelId`]: ../model/struct.ChannelId.html - /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong #[inline] pub fn say(&self, content: &str) -> Result<Message> { self.channel_id.say(content) @@ -282,11 +286,11 @@ impl Group { /// # Errors /// /// If the content of the message is over the above limit, then a - /// [`ClientError::MessageTooLong`] will be returned, containing the number + /// [`ModelError::MessageTooLong`] will be returned, containing the number /// of unicode code points over the limit. /// /// [`ChannelId::send_file`]: struct.ChannelId.html#method.send_file - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong /// [Attach Files]: permissions/constant.ATTACH_FILES.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html pub fn send_file<F, R>(&self, file: R, filename: &str, f: F) -> Result<Message> @@ -301,7 +305,7 @@ impl Group { /// /// **Note**: Requires the [Send Messages] permission. /// - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html #[inline] pub fn send_message<F: FnOnce(CreateMessage) -> CreateMessage>(&self, f: F) -> Result<Message> { diff --git a/src/model/channel/guild_channel.rs b/src/model/channel/guild_channel.rs index 7f05b4f..7180017 100644 --- a/src/model/channel/guild_channel.rs +++ b/src/model/channel/guild_channel.rs @@ -1,14 +1,17 @@ use std::fmt::{Display, Formatter, Result as FmtResult}; use std::io::Read; use std::mem; -use ::client::rest; use ::internal::prelude::*; use ::model::*; -use ::utils::builder::{CreateInvite, CreateMessage, EditChannel, GetMessages}; -use ::utils as serenity_utils; +#[cfg(feature="model")] +use ::builder::{CreateInvite, CreateMessage, EditChannel, GetMessages}; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; +#[cfg(feature="model")] +use ::http; +#[cfg(all(feature="model", feature="utils"))] +use ::utils as serenity_utils; /// Represents a guild's text or voice channel. Some methods are available only /// for voice channels and some are only available for text channels. @@ -62,6 +65,7 @@ pub struct GuildChannel { pub user_limit: Option<u64>, } +#[cfg(feature="model")] impl GuildChannel { /// Broadcasts to the channel that the current user is typing. /// @@ -71,10 +75,10 @@ impl GuildChannel { /// /// # Errors /// - /// Returns a [`ClientError::InvalidPermissions`] if the current user does + /// Returns a [`ModelError::InvalidPermissions`] if the current user does /// not have the required permissions. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Send Messages]: permissions/constant.SEND_MESSAGES.html pub fn broadcast_typing(&self) -> Result<()> { self.id.broadcast_typing() @@ -96,11 +100,11 @@ impl GuildChannel { let req = permissions::CREATE_INVITE; if !utils::user_has_perms(self.id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } - rest::create_invite(self.id.0, &f(CreateInvite::default()).0) + http::create_invite(self.id.0, &f(CreateInvite::default()).0) } /// Creates a [permission overwrite][`PermissionOverwrite`] for either a @@ -119,8 +123,8 @@ impl GuildChannel { /// permissions: /// /// ```rust,ignore - /// use serenity::client::CACHE; /// use serenity::model::{ChannelId, PermissionOverwrite, permissions}; + /// use serenity::CACHE; /// /// let channel_id = 7; /// let user_id = 8; @@ -145,8 +149,8 @@ impl GuildChannel { /// permissions: /// /// ```rust,ignore - /// use serenity::client::CACHE; /// use serenity::model::{ChannelId, PermissionOverwrite, permissions}; + /// use serenity::CACHE; /// /// let channel_id = 7; /// let user_id = 8; @@ -187,7 +191,7 @@ impl GuildChannel { let req = permissions::MANAGE_CHANNELS; if !utils::user_has_perms(self.id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -256,7 +260,7 @@ impl GuildChannel { let req = permissions::MANAGE_CHANNELS; if !utils::user_has_perms(self.id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -267,7 +271,7 @@ impl GuildChannel { let edited = f(EditChannel(map)).0; - match rest::edit_channel(self.id.0, &edited) { + match http::edit_channel(self.id.0, &edited) { Ok(channel) => { mem::replace(self, channel); @@ -288,14 +292,14 @@ impl GuildChannel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the [`the limit`], containing the number of unicode code points /// over the limit. /// - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [`Message`]: struct.Message.html - /// [`the limit`]: ../utils/builder/struct.CreateMessage.html#method.content + /// [`the limit`]: ../builder/struct.CreateMessage.html#method.content #[inline] pub fn edit_message<F, M>(&self, message_id: M, f: F) -> Result<Message> where F: FnOnce(CreateMessage) -> CreateMessage, M: Into<MessageId> { @@ -330,6 +334,7 @@ impl GuildChannel { /// [`ChannelType::Text`]: enum.ChannelType.html#variant.Text /// [`ChannelType::Voice`]: enum.ChannelType.html#variant.Voice /// [`utils::is_nsfw`]: ../utils/fn.is_nsfw.html + #[cfg(feature="utils")] #[inline] pub fn is_nsfw(&self) -> bool { self.kind == ChannelType::Text && serenity_utils::is_nsfw(&self.name) @@ -374,7 +379,7 @@ impl GuildChannel { /// # /// # let mut client = Client::login(""); /// # - /// use serenity::client::CACHE; + /// use serenity::CACHE; /// /// client.on_message(|_, msg| { /// let channel = match CACHE.read().unwrap().get_guild_channel(msg.channel_id) { @@ -397,7 +402,7 @@ impl GuildChannel { /// # /// # let mut client = Client::login(""); /// # - /// use serenity::client::CACHE; + /// use serenity::CACHE; /// use serenity::model::permissions; /// use std::fs::File; /// @@ -429,20 +434,21 @@ impl GuildChannel { /// /// # Errors /// - /// Returns a [`ClientError::GuildNotFound`] if the channel's guild could + /// Returns a [`ModelError::GuildNotFound`] if the channel's guild could /// not be found in the [`Cache`]. /// - /// [`Cache`]: ../ext/cache/struct.Cache.html - /// [`ClientError::GuildNotFound`]: ../client/enum.Error.html#variant.GuildNotFound + /// [`Cache`]: ../cache/struct.Cache.html + /// [`ModelError::GuildNotFound`]: enum.ModelError.html#variant.GuildNotFound /// [`Guild`]: struct.Guild.html /// [`Member`]: struct.Member.html /// [`Message`]: struct.Message.html /// [`User`]: struct.User.html /// [Attach Files]: permissions/constant.ATTACH_FILES.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html + #[cfg(feature="cache")] pub fn permissions_for<U: Into<UserId>>(&self, user_id: U) -> Result<Permissions> { self.guild() - .ok_or_else(|| Error::Client(ClientError::GuildNotFound)) + .ok_or_else(|| Error::Model(ModelError::GuildNotFound)) .map(|g| g.read().unwrap().permissions_for(self.id, user_id)) } @@ -483,12 +489,12 @@ impl GuildChannel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// - /// [`ChannelId`]: ../model/struct.ChannelId.html - /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong + /// [`ChannelId`]: struct.ChannelId.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong #[inline] pub fn say(&self, content: &str) -> Result<Message> { self.id.say(content) @@ -506,11 +512,11 @@ impl GuildChannel { /// # Errors /// /// If the content of the message is over the above limit, then a - /// [`ClientError::MessageTooLong`] will be returned, containing the number + /// [`ModelError::MessageTooLong`] will be returned, containing the number /// of unicode code points over the limit. /// /// [`ChannelId::send_file`]: struct.ChannelId.html#method.send_file - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong /// [Attach Files]: permissions/constant.ATTACH_FILES.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html pub fn send_file<F, R>(&self, file: R, filename: &str, f: F) -> Result<Message> @@ -526,15 +532,15 @@ impl GuildChannel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// - /// Returns a [`ClientError::InvalidPermissions`] if the current user does + /// Returns a [`ModelError::InvalidPermissions`] if the current user does /// not have the required permissions. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong /// [`Message`]: struct.Message.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html pub fn send_message<F: FnOnce(CreateMessage) -> CreateMessage>(&self, f: F) -> Result<Message> { @@ -543,7 +549,7 @@ impl GuildChannel { let req = permissions::SEND_MESSAGES; if !utils::user_has_perms(self.id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -623,6 +629,7 @@ impl GuildChannel { } } +#[cfg(feature="model")] impl Display for GuildChannel { /// Formats the channel, creating a mention of it. fn fmt(&self, f: &mut Formatter) -> FmtResult { diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs index 91f6c89..30f5850 100644 --- a/src/model/channel/message.rs +++ b/src/model/channel/message.rs @@ -1,14 +1,17 @@ use std::mem; use time; use ::constants; -use ::client::rest; use ::model::*; -use ::utils::builder::{CreateEmbed, CreateMessage}; + #[cfg(feature="cache")] use std::fmt::Write; +#[cfg(feature="model")] +use ::builder::{CreateEmbed, CreateMessage}; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; +#[cfg(feature="http")] +use ::http; /// A representation of a message over a guild's text channel, a group, or a /// private channel. @@ -61,6 +64,7 @@ pub struct Message { pub webhook_id: Option<WebhookId>, } +#[cfg(feature="model")] impl Message { /// Deletes the message. /// @@ -70,11 +74,11 @@ impl Message { /// # Errors /// /// If the `cache` feature is enabled, then returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have + /// [`ModelError::InvalidPermissions`] if the current user does not have /// the required permissions. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions - /// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions + /// [`ModelError::InvalidUser`]: enum.ModelError.html#variant.InvalidUser /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html pub fn delete(&self) -> Result<()> { #[cfg(feature="cache")] @@ -84,7 +88,7 @@ impl Message { let has_perms = utils::user_has_perms(self.channel_id, req)?; if !is_author && !has_perms { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -98,10 +102,10 @@ impl Message { /// # Errors /// /// If the `cache` feature is enabled, then returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have + /// [`ModelError::InvalidPermissions`] if the current user does not have /// the required permissions. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Reaction`]: struct.Reaction.html /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html pub fn delete_reactions(&self) -> Result<()> { @@ -110,11 +114,11 @@ impl Message { let req = permissions::MANAGE_MESSAGES; if !utils::user_has_perms(self.channel_id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } - rest::delete_message_reactions(self.channel_id.0, self.id.0) + http::delete_message_reactions(self.channel_id.0, self.id.0) } /// Edits this message, replacing the original content with new content. @@ -138,23 +142,23 @@ impl Message { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidUser`] if the + /// If the `cache` is enabled, returns a [`ModelError::InvalidUser`] if the /// current user is not the author. /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over [`the limit`], containing the number of unicode code points /// over the limit. /// - /// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html - /// [`the limit`]: ../utils/builder/struct.CreateMessage.html#method.content + /// [`ModelError::InvalidUser`]: enum.ModelError.html#variant.InvalidUser + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html + /// [`the limit`]: ../builder/struct.CreateMessage.html#method.content pub fn edit<F>(&mut self, f: F) -> Result<()> where F: FnOnce(CreateMessage) -> CreateMessage { #[cfg(feature="cache")] { if self.author.id != CACHE.read().unwrap().user.id { - return Err(Error::Client(ClientError::InvalidUser)); + return Err(Error::Model(ModelError::InvalidUser)); } } @@ -174,7 +178,7 @@ impl Message { let map = f(builder).0; - match rest::edit_message(self.channel_id.0, self.id.0, &Value::Object(map)) { + match http::edit_message(self.channel_id.0, self.id.0, &Value::Object(map)) { Ok(edited) => { mem::replace(self, edited); @@ -321,10 +325,10 @@ impl Message { /// # Errors /// /// If the `cache` is enabled, returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have + /// [`ModelError::InvalidPermissions`] if the current user does not have /// the required permissions. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html pub fn pin(&self) -> Result<()> { #[cfg(feature="cache")] @@ -332,7 +336,7 @@ impl Message { let req = permissions::MANAGE_MESSAGES; if !utils::user_has_perms(self.channel_id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -346,10 +350,10 @@ impl Message { /// # Errors /// /// If the `cache` is enabled, returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have - /// the required [permissions]. + /// [`ModelError::InvalidPermissions`] if the current user does not have the + /// required [permissions]. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Emoji`]: struct.Emoji.html /// [Add Reactions]: permissions/constant.ADD_REACTIONS.html /// [permissions]: permissions @@ -359,11 +363,11 @@ impl Message { let req = permissions::ADD_REACTIONS; if !utils::user_has_perms(self.channel_id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } - rest::create_reaction(self.channel_id.0, + http::create_reaction(self.channel_id.0, self.id.0, &reaction_type.into()) } @@ -380,19 +384,19 @@ impl Message { /// # Errors /// /// If the `cache` is enabled, returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have + /// [`ModelError::InvalidPermissions`] if the current user does not have /// the required permissions. /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong /// [Send Messages]: permissions/constant.SEND_MESSAGES.html 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))); + return Err(Error::Model(ModelError::MessageTooLong(length_over))); } #[cfg(feature="cache")] @@ -400,7 +404,7 @@ impl Message { let req = permissions::SEND_MESSAGES; if !utils::user_has_perms(self.channel_id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -413,7 +417,7 @@ impl Message { "tts": false, }); - rest::send_message(self.channel_id.0, &map) + http::send_message(self.channel_id.0, &map) } /// Unpins the message from its channel. @@ -423,10 +427,10 @@ impl Message { /// # Errors /// /// If the `cache` is enabled, returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have + /// [`ModelError::InvalidPermissions`] if the current user does not have /// the required permissions. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html pub fn unpin(&self) -> Result<()> { #[cfg(feature="cache")] @@ -434,11 +438,11 @@ impl Message { let req = permissions::MANAGE_MESSAGES; if !utils::user_has_perms(self.channel_id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } - rest::unpin_message(self.channel_id.0, self.id.0) + http::unpin_message(self.channel_id.0, self.id.0) } /// Alias of [`reaction_users`]. @@ -456,7 +460,7 @@ impl Message { if let Some(content) = map.get("content") { if let Value::String(ref content) = *content { if let Some(length_over) = Message::overflow_length(content) { - return Err(Error::Client(ClientError::MessageTooLong(length_over))); + return Err(Error::Model(ModelError::MessageTooLong(length_over))); } } } @@ -512,7 +516,7 @@ impl Message { } else { let overflow = total as u64 - constants::EMBED_MAX_LENGTH as u64; - Err(Error::Client(ClientError::EmbedTooLarge(overflow))) + Err(Error::Model(ModelError::EmbedTooLarge(overflow))) } } } diff --git a/src/model/channel/mod.rs b/src/model/channel/mod.rs index 33e4e9b..98e5f8d 100644 --- a/src/model/channel/mod.rs +++ b/src/model/channel/mod.rs @@ -22,7 +22,9 @@ use std::fmt::{Display, Formatter, Result as FmtResult}; use std::io::Read; use super::utils::deserialize_u64; use ::model::*; -use ::utils::builder::{CreateMessage, GetMessages}; + +#[cfg(feature="model")] +use ::builder::{CreateMessage, GetMessages}; /// A container for any channel. #[derive(Clone, Debug)] @@ -42,6 +44,7 @@ pub enum Channel { Private(Arc<RwLock<PrivateChannel>>), } +#[cfg(feature="model")] impl Channel { /// React to a [`Message`] with a custom [`Emoji`] or unicode character. /// @@ -151,14 +154,14 @@ impl Channel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the [`the limit`], containing the number of unicode code points /// over the limit. /// - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [`Message`]: struct.Message.html - /// [`the limit`]: ../utils/builder/struct.CreateMessage.html#method.content + /// [`the limit`]: ../builder/struct.CreateMessage.html#method.content #[inline] pub fn edit_message<F, M>(&self, message_id: M, f: F) -> Result<Message> where F: FnOnce(CreateMessage) -> CreateMessage, M: Into<MessageId> { @@ -170,6 +173,7 @@ impl Channel { /// Refer to [`utils::is_nsfw`] for more details. /// /// [`utils::is_nsfw`]: ../utils/fn.is_nsfw.html + #[cfg(feature="utils")] #[inline] pub fn is_nsfw(&self) -> bool { match *self { @@ -255,12 +259,12 @@ impl Channel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// - /// [`ChannelId`]: ../model/struct.ChannelId.html - /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong + /// [`ChannelId`]: struct.ChannelId.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong #[inline] pub fn say(&self, content: &str) -> Result<Message> { self.id().say(content) @@ -278,11 +282,11 @@ impl Channel { /// # Errors /// /// If the content of the message is over the above limit, then a - /// [`ClientError::MessageTooLong`] will be returned, containing the number + /// [`ModelError::MessageTooLong`] will be returned, containing the number /// of unicode code points over the limit. /// /// [`ChannelId::send_file`]: struct.ChannelId.html#method.send_file - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong /// [Attach Files]: permissions/constant.ATTACH_FILES.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html pub fn send_file<F, R>(&self, file: R, filename: &str, f: F) -> Result<Message> @@ -301,13 +305,13 @@ impl Channel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// /// [`Channel`]: enum.Channel.html - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html #[inline] pub fn send_message<F>(&self, f: F) -> Result<Message> @@ -384,6 +388,7 @@ impl<'de> Deserialize<'de> for Channel { } } +#[cfg(feature="model")] impl Display for Channel { /// Formats the channel into a "mentioned" string. /// @@ -487,9 +492,9 @@ impl<'de> Deserialize<'de> for PermissionOverwrite { /// The type of edit being made to a Channel's permissions. /// -/// This is for use with methods such as `Context::create_permission`. +/// This is for use with methods such as `GuildChannel::create_permission`. /// -/// [`Context::create_permission`]: ../client/ +/// [`GuildChannel::create_permission`]: struct.GuildChannel.html#method.create_permission #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum PermissionOverwriteType { /// A member which is having its permission overwrites edited. diff --git a/src/model/channel/private_channel.rs b/src/model/channel/private_channel.rs index 910daa2..9e2aec1 100644 --- a/src/model/channel/private_channel.rs +++ b/src/model/channel/private_channel.rs @@ -2,7 +2,9 @@ use std::fmt::{Display, Formatter, Result as FmtResult}; use std::io::Read; use super::deserialize_single_recipient; use ::model::*; -use ::utils::builder::{CreateMessage, GetMessages}; + +#[cfg(feature="model")] +use ::builder::{CreateMessage, GetMessages}; /// A Direct Message text channel with another user. #[derive(Clone, Debug, Deserialize)] @@ -29,6 +31,7 @@ pub struct PrivateChannel { pub recipient: Arc<RwLock<User>>, } +#[cfg(feature="model")] impl PrivateChannel { /// Broadcasts that the current user is typing to the recipient. pub fn broadcast_typing(&self) -> Result<()> { @@ -114,14 +117,14 @@ impl PrivateChannel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the [`the limit`], containing the number of unicode code points /// over the limit. /// - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [`Message`]: struct.Message.html - /// [`the limit`]: ../utils/builder/struct.CreateMessage.html#method.content + /// [`the limit`]: ../builder/struct.CreateMessage.html#method.content #[inline] pub fn edit_message<F, M>(&self, message_id: M, f: F) -> Result<Message> where F: FnOnce(CreateMessage) -> CreateMessage, M: Into<MessageId> { @@ -206,12 +209,12 @@ impl PrivateChannel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// /// [`ChannelId`]: ../model/struct.ChannelId.html - /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong #[inline] pub fn say(&self, content: &str) -> Result<Message> { self.id.say(content) @@ -229,11 +232,11 @@ impl PrivateChannel { /// # Errors /// /// If the content of the message is over the above limit, then a - /// [`ClientError::MessageTooLong`] will be returned, containing the number + /// [`ModelError::MessageTooLong`] will be returned, containing the number /// of unicode code points over the limit. /// /// [`ChannelId::send_file`]: struct.ChannelId.html#method.send_file - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong /// [Attach Files]: permissions/constant.ATTACH_FILES.html /// [Send Messages]: permissions/constant.SEND_MESSAGES.html pub fn send_file<F, R>(&self, file: R, filename: &str, f: F) -> Result<Message> @@ -248,12 +251,12 @@ impl PrivateChannel { /// /// # Errors /// - /// Returns a [`ClientError::MessageTooLong`] if the content of the message + /// Returns a [`ModelError::MessageTooLong`] if the content of the message /// is over the above limit, containing the number of unicode code points /// over the limit. /// - /// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong - /// [`CreateMessage`]: ../utils/builder/struct.CreateMessage.html + /// [`ModelError::MessageTooLong`]: enum.ModelError.html#variant.MessageTooLong + /// [`CreateMessage`]: ../builder/struct.CreateMessage.html /// [`Message`]: struct.Message.html #[inline] pub fn send_message<F: FnOnce(CreateMessage) -> CreateMessage>(&self, f: F) -> Result<Message> { diff --git a/src/model/channel/reaction.rs b/src/model/channel/reaction.rs index 9c3618d..132af7b 100644 --- a/src/model/channel/reaction.rs +++ b/src/model/channel/reaction.rs @@ -1,12 +1,14 @@ use serde::de::{Deserialize, Error as DeError, MapAccess, Visitor}; use std::fmt::{Display, Formatter, Result as FmtResult, Write as FmtWrite}; -use ::client::rest; use ::internal::prelude::*; use ::model::*; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; +#[cfg(feature="model")] +use ::http; +#[cfg(feature="model")] impl Reaction { /// Deletes the reaction, but only if the current user is the user who made /// the reaction or has permission to. @@ -17,10 +19,10 @@ impl Reaction { /// # Errors /// /// If the `cache` is enabled, then returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have + /// [`ModelError::InvalidPermissions`] if the current user does not have /// the required [permissions]. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html /// [permissions]: permissions pub fn delete(&self) -> Result<()> { @@ -41,7 +43,7 @@ impl Reaction { let req = permissions::MANAGE_MESSAGES; if !utils::user_has_perms(self.channel_id, req).unwrap_or(true) { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -50,7 +52,7 @@ impl Reaction { Some(self.user_id.0) }}; - rest::delete_reaction(self.channel_id.0, + http::delete_reaction(self.channel_id.0, self.message_id.0, user_id, &self.emoji) @@ -70,10 +72,10 @@ impl Reaction { /// /// # Errors /// - /// Returns a [`ClientError::InvalidPermissions`] if the current user does + /// Returns a [`ModelError::InvalidPermissions`] if the current user does /// not have the required [permissions]. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Emoji`]: struct.Emoji.html /// [`Message`]: struct.Message.html /// [`User`]: struct.User.html @@ -86,7 +88,7 @@ impl Reaction { -> Result<Vec<User>> where R: Into<ReactionType>, U: Into<UserId> { - rest::get_reaction_users(self.channel_id.0, + http::get_reaction_users(self.channel_id.0, self.message_id.0, &reaction_type.into(), limit.unwrap_or(50), @@ -201,6 +203,7 @@ impl<'de> Deserialize<'de> for ReactionType { } } +#[cfg(any(feature="model", feature="http"))] impl ReactionType { /// Creates a data-esque display of the type. This is not very useful for /// displaying, as the primary client can not render it, but can be useful diff --git a/src/model/error.rs b/src/model/error.rs new file mode 100644 index 0000000..6d0295b --- /dev/null +++ b/src/model/error.rs @@ -0,0 +1,109 @@ +use std::error::Error as StdError; +use std::fmt::{Display, Formatter, Result as FmtResult}; +use super::Permissions; + +/// An error returned from the [`model`] module. +/// +/// This is always wrapped within the library's [`Error::Model`] variant. +/// +/// # Examples +/// +/// Matching an [`Error`] with this variant would look something like the +/// following for the [`GuildId::ban`] method, which in this example is used to +/// re-ban all members with an odd discriminator: +/// +/// ```rust,no_run +/// use serenity::{Client, Error}; +/// use serenity::model::ModelError; +/// use std::env; +/// +/// let token = env::var("DISCORD_BOT_TOKEN").unwrap(); +/// let mut client = Client::login(&token); +/// +/// client.on_member_unban(|context, guild_id, user| { +/// // If the user has an even discriminator, don't re-ban them. +/// if user.discriminator % 2 == 0 { +/// return; +/// } +/// +/// match guild_id.ban(user, 8) { +/// Ok(()) => { +/// // Ban successful. +/// }, +/// Err(Error::Model(ModelError::DeleteMessageDaysAmount(amount))) => { +/// println!("Failed deleting {} days' worth of messages", amount); +/// }, +/// Err(why) => { +/// println!("Unexpected error: {:?}", why); +/// }, +/// } +/// }); +/// ``` +/// +/// [`Error`]: ../enum.Error.html +/// [`Error::Model`]: ../enum.Error.html#variant.Model +/// [`GuildId::ban`]: struct.GuildId.html#method.ban +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub enum Error { + /// When attempting to delete below or above the minimum and maximum allowed + /// number of messages. + BulkDeleteAmount, + /// When attempting to delete a number of days' worth of messages that is + /// not allowed. + DeleteMessageDaysAmount(u8), + /// Indicates that the textual content of an embed exceeds the maximum + /// length. + EmbedTooLarge(u64), + /// An indication that a [guild][`Guild`] could not be found by + /// [Id][`GuildId`] in the [`Cache`]. + /// + /// [`Guild`]: ../model/struct.Guild.html + /// [`GuildId`]: ../model/struct.GuildId.html + /// [`Cache`]: ../cache/struct.Cache.html + GuildNotFound, + /// Indicates that you do not have the required permissions to perform an + /// operation. + /// + /// The provided [`Permission`]s is the set of required permissions + /// required. + /// + /// [`Permission`]: ../model/permissions/struct.Permissions.html + InvalidPermissions(Permissions), + /// An indicator that the [current user] can not perform an action. + /// + /// [current user]: ../model/struct.CurrentUser.html + InvalidUser, + /// An indicator that an item is missing from the [`Cache`], and the action + /// can not be continued. + /// + /// [`Cache`]: ../cache/struct.Cache.html + ItemMissing, + /// Indicates that a [`Message`]s content was too long and will not + /// successfully send, as the length is over 2000 codepoints, or 4000 bytes. + /// + /// The number of bytes larger than the limit is provided. + /// + /// [`Message`]: ../model/struct.Message.html + MessageTooLong(u64), +} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + f.write_str(self.description()) + } +} + +impl StdError for Error { + fn description(&self) -> &str { + match *self { + Error::BulkDeleteAmount => "Too few/many messages to bulk delete", + Error::DeleteMessageDaysAmount(_) => "Invalid delete message days", + Error::EmbedTooLarge(_) => "Embed too large", + Error::GuildNotFound => "Guild not found in the cache", + Error::InvalidPermissions(_) => "Invalid permissions", + Error::InvalidUser => "The current user can not perform the action", + Error::ItemMissing => "The required item is missing from the cache", + Error::MessageTooLong(_) => "Message too large", + } + } +} diff --git a/src/model/event.rs b/src/model/event.rs index c658ee2..26f7e70 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -8,6 +8,9 @@ use super::*; use ::constants::{OpCode, VoiceOpCode}; use ::internal::prelude::*; +#[cfg(feature="gateway")] +use ::gateway::GatewayError; + /// Event data for the channel creation event. /// /// This is fired when: @@ -452,6 +455,7 @@ pub enum GatewayEvent { } impl GatewayEvent { + #[cfg(feature="gateway")] pub fn decode(value: Value) -> Result<Self> { let mut map = JsonMap::deserialize(value)?; @@ -492,7 +496,7 @@ impl GatewayEvent { GatewayEvent::Hello(interval) }, OpCode::HeartbeatAck => GatewayEvent::HeartbeatAck, - _ => return Err(Error::Client(ClientError::InvalidOpCode)), + _ => return Err(Error::Gateway(GatewayError::InvalidOpCode)), }) } } @@ -708,7 +712,7 @@ pub struct VoiceSpeaking { /// A representation of data received for [`voice`] events. /// -/// [`voice`]: ../../ext/voice/index.html +/// [`voice`]: ../../voice/index.html #[derive(Clone, Debug)] pub enum VoiceEvent { /// A voice heartbeat. diff --git a/src/model/gateway.rs b/src/model/gateway.rs index ea2a1b3..52ec9b0 100644 --- a/src/model/gateway.rs +++ b/src/model/gateway.rs @@ -34,6 +34,7 @@ pub struct Game { pub url: Option<String>, } +#[cfg(feature="model")] impl Game { /// Creates a `Game` struct that appears as a `Playing <name>` status. /// diff --git a/src/model/guild/emoji.rs b/src/model/guild/emoji.rs index 4c2b6fc..2de4e30 100644 --- a/src/model/guild/emoji.rs +++ b/src/model/guild/emoji.rs @@ -1,14 +1,16 @@ use std::fmt::{Display, Formatter, Result as FmtResult, Write as FmtWrite}; -use ::model::{EmojiId, RoleId}; +use super::super::{EmojiId, ModelError, RoleId}; #[cfg(feature="cache")] use std::mem; #[cfg(feature="cache")] -use ::client::{CACHE, rest}; +use ::CACHE; #[cfg(feature="cache")] use ::internal::prelude::*; +#[cfg(feature="model")] +use ::http; #[cfg(feature="cache")] -use ::model::GuildId; +use super::super::GuildId; /// Represents a custom guild emoji, which can either be created using the API, /// or via an integration. Emojis created using the API only work within the @@ -34,6 +36,7 @@ pub struct Emoji { pub roles: Vec<RoleId>, } +#[cfg(feature="model")] impl Emoji { /// Deletes the emoji. /// @@ -45,8 +48,8 @@ impl Emoji { #[cfg(feature="cache")] pub fn delete(&self) -> Result<()> { match self.find_guild_id() { - Some(guild_id) => rest::delete_emoji(guild_id.0, self.id.0), - None => Err(Error::Client(ClientError::ItemMissing)), + Some(guild_id) => http::delete_emoji(guild_id.0, self.id.0), + None => Err(Error::Model(ModelError::ItemMissing)), } } @@ -65,7 +68,7 @@ impl Emoji { "name": name, }); - match rest::edit_emoji(guild_id.0, self.id.0, &map) { + match http::edit_emoji(guild_id.0, self.id.0, &map) { Ok(emoji) => { mem::replace(self, emoji); @@ -74,7 +77,7 @@ impl Emoji { Err(why) => Err(why), } }, - None => Err(Error::Client(ClientError::ItemMissing)), + None => Err(Error::Model(ModelError::ItemMissing)), } } diff --git a/src/model/guild/guild_id.rs b/src/model/guild/guild_id.rs index d1866ed..6975e6d 100644 --- a/src/model/guild/guild_id.rs +++ b/src/model/guild/guild_id.rs @@ -1,12 +1,15 @@ use std::fmt::{Display, Formatter, Result as FmtResult}; -use ::client::rest; use ::internal::prelude::*; use ::model::*; -use ::utils::builder::{EditGuild, EditMember, EditRole}; +#[cfg(feature="model")] +use ::builder::{EditGuild, EditMember, EditRole}; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; +#[cfg(feature="http")] +use ::http; +#[cfg(feature="model")] impl GuildId { /// Converts the guild Id into the default channel's Id. #[inline] @@ -34,20 +37,20 @@ impl GuildId { /// /// # Errors /// - /// Returns a [`ClientError::DeleteMessageDaysAmount`] if the number of + /// Returns a [`ModelError::DeleteMessageDaysAmount`] if the number of /// days' worth of messages to delete is over the maximum. /// - /// [`ClientError::DeleteMessageDaysAmount`]: ../client/enum.ClientError.html#variant.DeleteMessageDaysAmount + /// [`ModelError::DeleteMessageDaysAmount`]: enum.ModelError.html#variant.DeleteMessageDaysAmount /// [`Guild::ban`]: struct.Guild.html#method.ban /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html pub fn ban<U: Into<UserId>>(&self, user: U, delete_message_days: u8) -> Result<()> { if delete_message_days > 7 { - return Err(Error::Client(ClientError::DeleteMessageDaysAmount(delete_message_days))); + return Err(Error::Model(ModelError::DeleteMessageDaysAmount(delete_message_days))); } - rest::ban_user(self.0, user.into().0, delete_message_days) + http::ban_user(self.0, user.into().0, delete_message_days) } /// Gets a list of the guild's bans. @@ -57,7 +60,7 @@ impl GuildId { /// [Ban Members]: permissions/constant.BAN_MEMBERS.html #[inline] pub fn bans(&self) -> Result<Vec<Ban>> { - rest::get_bans(self.0) + http::get_bans(self.0) } /// Gets all of the guild's channels over the REST API. @@ -66,7 +69,7 @@ impl GuildId { pub fn channels(&self) -> Result<HashMap<ChannelId, GuildChannel>> { let mut channels = HashMap::new(); - for channel in rest::get_channels(self.0)? { + for channel in http::get_channels(self.0)? { channels.insert(channel.id, channel); } @@ -75,7 +78,7 @@ impl GuildId { /// Creates a [`GuildChannel`] in the the guild. /// - /// Refer to [`rest::create_channel`] for more information. + /// Refer to [`http::create_channel`] for more information. /// /// Requires the [Manage Channels] permission. /// @@ -90,7 +93,7 @@ impl GuildId { /// ``` /// /// [`GuildChannel`]: struct.GuildChannel.html - /// [`rest::create_channel`]: ../client/rest/fn.create_channel.html + /// [`http::create_channel`]: ../http/fn.create_channel.html /// [Manage Channels]: permissions/constant.MANAGE_CHANNELS.html pub fn create_channel(&self, name: &str, kind: ChannelType) -> Result<GuildChannel> { let map = json!({ @@ -98,7 +101,7 @@ impl GuildId { "type": kind.name(), }); - rest::create_channel(self.0, &map) + http::create_channel(self.0, &map) } /// Creates an emoji in the guild with a name and base64-encoded image. @@ -114,7 +117,7 @@ impl GuildId { /// how to read an image from the filesystem and encode it as base64. Most /// of the example can be applied similarly for this method. /// - /// [`EditProfile::avatar`]: ../utils/builder/struct.EditProfile.html#method.avatar + /// [`EditProfile::avatar`]: ../builder/struct.EditProfile.html#method.avatar /// [`Guild::create_emoji`]: struct.Guild.html#method.create_emoji /// [`utils::read_image`]: ../utils/fn.read_image.html /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html @@ -124,7 +127,7 @@ impl GuildId { "image": image, }); - rest::create_emoji(self.0, &map) + http::create_emoji(self.0, &map) } /// Creates an integration for the guild. @@ -140,7 +143,7 @@ impl GuildId { "type": kind, }); - rest::create_guild_integration(self.0, integration_id.0, &map) + http::create_guild_integration(self.0, integration_id.0, &map) } /// Creates a new role in the guild with the data set, if any. @@ -153,7 +156,7 @@ impl GuildId { /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html #[inline] pub fn create_role<F: FnOnce(EditRole) -> EditRole>(&self, f: F) -> Result<Role> { - rest::create_role(self.0, &f(EditRole::default()).0) + http::create_role(self.0, &f(EditRole::default()).0) } /// Deletes the current guild if the current account is the owner of the @@ -166,7 +169,7 @@ impl GuildId { /// [`Guild::delete`]: struct.Guild.html#method.delete #[inline] pub fn delete(&self) -> Result<PartialGuild> { - rest::delete_guild(self.0) + http::delete_guild(self.0) } /// Deletes an [`Emoji`] from the guild. @@ -177,7 +180,7 @@ impl GuildId { /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html #[inline] pub fn delete_emoji<E: Into<EmojiId>>(&self, emoji_id: E) -> Result<()> { - rest::delete_emoji(self.0, emoji_id.into().0) + http::delete_emoji(self.0, emoji_id.into().0) } /// Deletes an integration by Id from the guild. @@ -187,7 +190,7 @@ impl GuildId { /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html #[inline] pub fn delete_integration<I: Into<IntegrationId>>(&self, integration_id: I) -> Result<()> { - rest::delete_guild_integration(self.0, integration_id.into().0) + http::delete_guild_integration(self.0, integration_id.into().0) } /// Deletes a [`Role`] by Id from the guild. @@ -202,7 +205,7 @@ impl GuildId { /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html #[inline] pub fn delete_role<R: Into<RoleId>>(&self, role_id: R) -> Result<()> { - rest::delete_role(self.0, role_id.into().0) + http::delete_role(self.0, role_id.into().0) } /// Edits the current guild with new data where specified. @@ -216,7 +219,7 @@ impl GuildId { /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html #[inline] pub fn edit<F: FnOnce(EditGuild) -> EditGuild>(&mut self, f: F) -> Result<PartialGuild> { - rest::edit_guild(self.0, &f(EditGuild::default()).0) + http::edit_guild(self.0, &f(EditGuild::default()).0) } /// Edits an [`Emoji`]'s name in the guild. @@ -234,7 +237,7 @@ impl GuildId { "name": name, }); - rest::edit_emoji(self.0, emoji_id.into().0, &map) + http::edit_emoji(self.0, emoji_id.into().0, &map) } /// Edits the properties of member of the guild, such as muting or @@ -253,7 +256,7 @@ impl GuildId { #[inline] pub fn edit_member<F, U>(&self, user_id: U, f: F) -> Result<()> where F: FnOnce(EditMember) -> EditMember, U: Into<UserId> { - rest::edit_member(self.0, user_id.into().0, &f(EditMember::default()).0) + http::edit_member(self.0, user_id.into().0, &f(EditMember::default()).0) } /// Edits the current user's nickname for the guild. @@ -265,7 +268,7 @@ impl GuildId { /// [Change Nickname]: permissions/constant.CHANGE_NICKNAME.html #[inline] pub fn edit_nickname(&self, new_nickname: Option<&str>) -> Result<()> { - rest::edit_nickname(self.0, new_nickname) + http::edit_nickname(self.0, new_nickname) } /// Edits a [`Role`], optionally setting its new fields. @@ -287,7 +290,7 @@ impl GuildId { #[inline] pub fn edit_role<F, R>(&self, role_id: R, f: F) -> Result<Role> where F: FnOnce(EditRole) -> EditRole, R: Into<RoleId> { - rest::edit_role(self.0, role_id.into().0, &f(EditRole::default()).0) + http::edit_role(self.0, role_id.into().0, &f(EditRole::default()).0) } /// Gets an emoji in the guild by Id. @@ -297,7 +300,7 @@ impl GuildId { /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html #[inline] pub fn emoji<E: Into<EmojiId>>(&self, emoji_id: E) -> Result<Emoji> { - rest::get_emoji(self.0, emoji_id.into().0) + http::get_emoji(self.0, emoji_id.into().0) } /// Gets a list of all of the guild's emojis. @@ -307,7 +310,7 @@ impl GuildId { /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html #[inline] pub fn emojis(&self) -> Result<Vec<Emoji>> { - rest::get_emojis(self.0) + http::get_emojis(self.0) } /// Search the cache for the guild. @@ -322,7 +325,7 @@ impl GuildId { /// all data with a guild retrieval. #[inline] pub fn get(&self) -> Result<PartialGuild> { - rest::get_guild(self.0) + http::get_guild(self.0) } /// Gets all integration of the guild. @@ -330,7 +333,7 @@ impl GuildId { /// This performs a request over the REST API. #[inline] pub fn integrations(&self) -> Result<Vec<Integration>> { - rest::get_guild_integrations(self.0) + http::get_guild_integrations(self.0) } /// Gets all of the guild's invites. @@ -340,7 +343,7 @@ impl GuildId { /// [Manage Guild]: permissions/struct.MANAGE_GUILD.html #[inline] pub fn invites(&self) -> Result<Vec<RichInvite>> { - rest::get_guild_invites(self.0) + http::get_guild_invites(self.0) } /// Kicks a [`Member`] from the guild. @@ -351,13 +354,13 @@ impl GuildId { /// [Kick Members]: permissions/constant.KICK_MEMBERS.html #[inline] pub fn kick<U: Into<UserId>>(&self, user_id: U) -> Result<()> { - rest::kick_member(self.0, user_id.into().0) + http::kick_member(self.0, user_id.into().0) } /// Leaves the guild. #[inline] pub fn leave(&self) -> Result<()> { - rest::leave_guild(self.0) + http::leave_guild(self.0) } /// Gets a user's [`Member`] for the guild by Id. @@ -366,7 +369,7 @@ impl GuildId { /// [`Member`]: struct.Member.html #[inline] pub fn member<U: Into<UserId>>(&self, user_id: U) -> Result<Member> { - rest::get_member(self.0, user_id.into().0) + http::get_member(self.0, user_id.into().0) } /// Gets a list of the guild's members. @@ -379,7 +382,7 @@ impl GuildId { #[inline] pub fn members<U>(&self, limit: Option<u64>, after: Option<U>) -> Result<Vec<Member>> where U: Into<UserId> { - rest::get_guild_members(self.0, limit, after.map(|x| x.into().0)) + http::get_guild_members(self.0, limit, after.map(|x| x.into().0)) } /// Moves a member to a specific voice channel. @@ -392,7 +395,7 @@ impl GuildId { let mut map = Map::new(); map.insert("channel_id".to_owned(), Value::Number(Number::from(channel_id.into().0))); - rest::edit_member(self.0, user_id.into().0, &map) + http::edit_member(self.0, user_id.into().0, &map) } /// Gets the number of [`Member`]s that would be pruned with the given @@ -407,7 +410,7 @@ impl GuildId { "days": days, }); - rest::get_guild_prune_count(self.0, &map) + http::get_guild_prune_count(self.0, &map) } /// Returns the Id of the shard associated with the guild. @@ -420,7 +423,7 @@ impl GuildId { /// total, consider using [`utils::shard_id`]. /// /// [`utils::shard_id`]: ../utils/fn.shard_id.html - #[cfg(feature="cache")] + #[cfg(all(feature="cache", feature="utils"))] #[inline] pub fn shard_id(&self) -> u64 { ::utils::shard_id(self.0, CACHE.read().unwrap().shard_count) @@ -447,7 +450,7 @@ impl GuildId { /// /// assert_eq!(guild_id.shard_id(17), 7); /// ``` - #[cfg(not(feature="cache"))] + #[cfg(all(feature="utils", not(feature="cache")))] #[inline] pub fn shard_id(&self, shard_count: u64) -> u64 { ::utils::shard_id(self.0, shard_count) @@ -460,7 +463,7 @@ impl GuildId { /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html #[inline] pub fn start_integration_sync<I: Into<IntegrationId>>(&self, integration_id: I) -> Result<()> { - rest::start_integration_sync(self.0, integration_id.into().0) + http::start_integration_sync(self.0, integration_id.into().0) } /// Starts a prune of [`Member`]s. @@ -478,7 +481,7 @@ impl GuildId { "days": days, }); - rest::start_guild_prune(self.0, &map) + http::start_guild_prune(self.0, &map) } /// Unbans a [`User`] from the guild. @@ -489,7 +492,7 @@ impl GuildId { /// [Ban Members]: permissions/constant.BAN_MEMBERS.html #[inline] pub fn unban<U: Into<UserId>>(&self, user_id: U) -> Result<()> { - rest::remove_ban(self.0, user_id.into().0) + http::remove_ban(self.0, user_id.into().0) } /// Retrieves the guild's webhooks. @@ -499,7 +502,7 @@ impl GuildId { /// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html #[inline] pub fn webhooks(&self) -> Result<Vec<Webhook>> { - rest::get_guild_webhooks(self.0) + http::get_guild_webhooks(self.0) } /// Alias of [`bans`]. diff --git a/src/model/guild/member.rs b/src/model/guild/member.rs index ddb0822..9c00acd 100644 --- a/src/model/guild/member.rs +++ b/src/model/guild/member.rs @@ -4,12 +4,14 @@ use super::deserialize_sync_user; use ::model::*; #[cfg(feature="cache")] -use ::client::{CACHE, rest}; +use ::CACHE; #[cfg(feature="cache")] use ::internal::prelude::*; -#[cfg(feature="cache")] -use ::utils::builder::EditMember; -#[cfg(feature="cache")] +#[cfg(feature="model")] +use ::http; +#[cfg(feature="builder")] +use ::builder::EditMember; +#[cfg(feature="utils")] use ::utils::Colour; /// Information about a member of a guild. @@ -34,6 +36,7 @@ pub struct Member { pub user: Arc<RwLock<User>>, } +#[cfg(feature="model")] impl Member { /// Adds a [`Role`] to the member, editing its roles in-place if the request /// was successful. @@ -52,7 +55,7 @@ impl Member { let guild_id = self.find_guild()?; - match rest::add_member_role(guild_id.0, self.user.read().unwrap().id.0, role_id.0) { + match http::add_member_role(guild_id.0, self.user.read().unwrap().id.0, role_id.0) { Ok(()) => { self.roles.push(role_id); @@ -76,7 +79,7 @@ impl Member { let map = EditMember::default().roles(&self.roles).0; - match rest::edit_member(guild_id.0, self.user.read().unwrap().id.0, &map) { + match http::edit_member(guild_id.0, self.user.read().unwrap().id.0, &map) { Ok(()) => Ok(()), Err(why) => { self.roles.retain(|r| !role_ids.contains(r)); @@ -93,15 +96,15 @@ impl Member { /// /// # Errors /// - /// Returns a [`ClientError::GuildNotFound`] if the guild could not be + /// Returns a [`ModelError::GuildNotFound`] if the guild could not be /// found. /// - /// [`ClientError::GuildNotFound`]: ../client/enum.ClientError.html#variant.GuildNotFound + /// [`ModelError::GuildNotFound`]: enum.ModelError.html#variant.GuildNotFound /// /// [Ban Members]: permissions/constant.BAN_MEMBERS.html #[cfg(feature="cache")] pub fn ban(&self, delete_message_days: u8) -> Result<()> { - rest::ban_user(self.find_guild()?.0, self.user.read().unwrap().id.0, delete_message_days) + http::ban_user(self.find_guild()?.0, self.user.read().unwrap().id.0, delete_message_days) } /// Determines the member's colour. @@ -158,7 +161,7 @@ impl Member { let guild_id = self.find_guild()?; let map = f(EditMember::default()).0; - rest::edit_member(guild_id.0, self.user.read().unwrap().id.0, &map) + http::edit_member(guild_id.0, self.user.read().unwrap().id.0, &map) } /// Finds the Id of the [`Guild`] that the member is in. @@ -168,11 +171,11 @@ impl Member { /// /// # Errors /// - /// Returns a [`ClientError::GuildNotFound`] if the guild could not be + /// Returns a [`ModelError::GuildNotFound`] if the guild could not be /// found. /// - /// [`Cache`]: ../ext/cache/struct.Cache.html - /// [`ClientError::GuildNotFound`]: ../client/enum.ClientError.html#variant.GuildNotFound + /// [`Cache`]: ../cache/struct.Cache.html + /// [`ModelError::GuildNotFound`]: enum.ModelError.html#variant.GuildNotFound /// [`Guild`]: struct.Guild.html /// [`Member::guild_id`]: struct.Member.html#structfield.guild_id #[cfg(feature="cache")] @@ -193,7 +196,7 @@ impl Member { } } - Err(Error::Client(ClientError::GuildNotFound)) + Err(Error::Model(ModelError::GuildNotFound)) } /// Kick the member from the guild. @@ -208,10 +211,10 @@ impl Member { /// // assuming a `member` has already been bound /// match member.kick() { /// Ok(()) => println!("Successfully kicked member"), - /// Err(Error::Client(ClientError::GuildNotFound)) => { + /// Err(Error::Model(ModelError::GuildNotFound)) => { /// println!("Couldn't determine guild of member"); /// }, - /// Err(Error::Client(ClientError::InvalidPermissions(missing_perms))) => { + /// Err(Error::Model(ModelError::InvalidPermissions(missing_perms))) => { /// println!("Didn't have permissions; missing: {:?}", missing_perms); /// }, /// _ => {}, @@ -220,14 +223,14 @@ impl Member { /// /// # Errors /// - /// Returns a [`ClientError::GuildNotFound`] if the Id of the member's guild + /// Returns a [`ModelError::GuildNotFound`] if the Id of the member's guild /// could not be determined. /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform the kick. /// - /// [`ClientError::GuildNotFound`]: ../client/enum.ClientError.html#variant.GuildNotFound - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::GuildNotFound`]: enum.ModelError.html#variant.GuildNotFound + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Kick Members]: permissions/constant.KICK_MEMBERS.html pub fn kick(&self) -> Result<()> { let guild_id; @@ -245,13 +248,13 @@ impl Member { .map(|guild| guild.read().unwrap().has_perms(req)); if let Some(Ok(false)) = has_perms { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } #[cfg(not(feature="cache"))] { - guild_id = self.guild_id.ok_or_else(|| Error::Client(ClientError::GuildNotFound))?; + guild_id = self.guild_id.ok_or_else(|| Error::Model(ModelError::GuildNotFound))?; } guild_id.kick(self.user.read().unwrap().id) @@ -274,7 +277,7 @@ impl Member { let guild_id = self.find_guild()?; - match rest::remove_member_role(guild_id.0, self.user.read().unwrap().id.0, role_id.0) { + match http::remove_member_role(guild_id.0, self.user.read().unwrap().id.0, role_id.0) { Ok(()) => { self.roles.retain(|r| r.0 != role_id.0); @@ -297,7 +300,7 @@ impl Member { let map = EditMember::default().roles(&self.roles).0; - match rest::edit_member(guild_id.0, self.user.read().unwrap().id.0, &map) { + match http::edit_member(guild_id.0, self.user.read().unwrap().id.0, &map) { Ok(()) => Ok(()), Err(why) => { self.roles.extend_from_slice(role_ids); @@ -339,15 +342,15 @@ impl Member { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html #[cfg(feature="cache")] pub fn unban(&self) -> Result<()> { - rest::remove_ban(self.find_guild()?.0, self.user.read().unwrap().id.0) + http::remove_ban(self.find_guild()?.0, self.user.read().unwrap().id.0) } } diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index de2c646..a3d37d0 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -17,13 +17,15 @@ pub use self::role::*; use serde::de::Error as DeError; use serde_json; use super::utils::*; -use ::client::rest; use ::constants::LARGE_THRESHOLD; use ::model::*; -use ::utils::builder::{EditGuild, EditMember, EditRole}; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; +#[cfg(feature="http")] +use ::http; +#[cfg(feature="model")] +use ::builder::{EditGuild, EditMember, EditRole}; /// A representation of a banning of a user. #[derive(Clone, Debug, Deserialize)] @@ -118,12 +120,13 @@ pub struct Guild { pub voice_states: HashMap<UserId, VoiceState>, } +#[cfg(feature="model")] impl Guild { #[cfg(feature="cache")] fn has_perms(&self, mut permissions: Permissions) -> Result<bool> { let member = match self.members.get(&CACHE.read().unwrap().user.id) { Some(member) => member, - None => return Err(Error::Client(ClientError::ItemMissing)), + None => return Err(Error::Model(ModelError::ItemMissing)), }; let perms = self.permissions_for(ChannelId(self.id.0), member.user.read().unwrap().id); @@ -150,21 +153,21 @@ impl Guild { /// /// # Errors /// - /// Returns a [`ClientError::InvalidPermissions`] if the current user does + /// Returns a [`ModelError::InvalidPermissions`] if the current user does /// not have permission to perform bans. /// - /// Returns a [`ClientError::DeleteMessageDaysAmount`] if the number of + /// Returns a [`ModelError::DeleteMessageDaysAmount`] if the number of /// days' worth of messages to delete is over the maximum. /// - /// [`ClientError::DeleteMessageDaysAmount`]: ../client/enum.ClientError.html#variant.DeleteMessageDaysAmount - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::DeleteMessageDaysAmount`]: enum.ModelError.html#variant.DeleteMessageDaysAmount + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Guild::ban`]: struct.Guild.html#method.ban /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html pub fn ban<U: Into<UserId>>(&self, user: U, delete_message_days: u8) -> Result<()> { if delete_message_days > 7 { - return Err(Error::Client(ClientError::DeleteMessageDaysAmount(delete_message_days))); + return Err(Error::Model(ModelError::DeleteMessageDaysAmount(delete_message_days))); } #[cfg(feature="cache")] @@ -172,7 +175,7 @@ impl Guild { let req = permissions::BAN_MEMBERS; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -185,11 +188,11 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// /// [`Ban`]: struct.Ban.html - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Ban Members]: permissions/constant.BAN_MEMBERS.html pub fn bans(&self) -> Result<Vec<Ban>> { #[cfg(feature="cache")] @@ -197,7 +200,7 @@ impl Guild { let req = permissions::BAN_MEMBERS; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -234,7 +237,7 @@ impl Guild { /// /// [`Guild`]: struct.Guild.html /// [`PartialGuild`]: struct.PartialGuild.html - /// [`Shard`]: ../client/gateway/struct.Shard.html + /// [`Shard`]: ../gateway/struct.Shard.html /// [US West region]: enum.Region.html#variant.UsWest /// [whitelist]: https://discordapp.com/developers/docs/resources/guild#create-guild pub fn create(name: &str, region: Region, icon: Option<&str>) -> Result<PartialGuild> { @@ -244,7 +247,7 @@ impl Guild { "region": region.name(), }); - rest::create_guild(&map) + http::create_guild(&map) } /// Creates a new [`Channel`] in the guild. @@ -263,11 +266,11 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// /// [`Channel`]: struct.Channel.html - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Manage Channels]: permissions/constant.MANAGE_CHANNELS.html pub fn create_channel(&mut self, name: &str, kind: ChannelType) -> Result<GuildChannel> { #[cfg(feature="cache")] @@ -275,7 +278,7 @@ impl Guild { let req = permissions::MANAGE_CHANNELS; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -298,8 +301,8 @@ impl Guild { /// how to read an image from the filesystem and encode it as base64. Most /// of the example can be applied similarly for this method. /// - /// [`EditProfile::avatar`]: ../utils/builder/struct.EditProfile.html#method.avatar - /// [`utils::read_image`]: ../utils/fn.read_image.html + /// [`EditProfile::avatar`]: ../builder/struct.EditProfile.html#method.avatar + /// [`utils::read_image`]: ../fn.read_image.html /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html #[inline] pub fn create_emoji(&self, name: &str, image: &str) -> Result<Emoji> { @@ -333,10 +336,10 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Context::create_role`]: ../client/struct.Context.html#method.create_role /// [`Role`]: struct.Role.html /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html @@ -347,7 +350,7 @@ impl Guild { let req = permissions::MANAGE_ROLES; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -361,17 +364,17 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, then returns a [`ClientError::InvalidUser`] + /// If the `cache` is enabled, then returns a [`ModelError::InvalidUser`] /// if the current user is not the guild owner. /// - /// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser + /// [`ModelError::InvalidUser`]: enum.ModelError.html#variant.InvalidUser pub fn delete(&self) -> Result<PartialGuild> { #[cfg(feature="cache")] { if self.owner_id != CACHE.read().unwrap().user.id { let req = permissions::MANAGE_GUILD; - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -437,10 +440,10 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Context::edit_guild`]: ../client/struct.Context.html#method.edit_guild /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html pub fn edit<F>(&mut self, f: F) -> Result<()> @@ -450,7 +453,7 @@ impl Guild { let req = permissions::MANAGE_GUILD; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -518,11 +521,11 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to change their own /// nickname. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Change Nickname]: permissions/constant.CHANGE_NICKNAME.html pub fn edit_nickname(&self, new_nickname: Option<&str>) -> Result<()> { #[cfg(feature="cache")] @@ -530,7 +533,7 @@ impl Guild { let req = permissions::CHANGE_NICKNAME; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -604,10 +607,10 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html pub fn invites(&self) -> Result<Vec<RichInvite>> { #[cfg(feature="cache")] @@ -615,7 +618,7 @@ impl Guild { let req = permissions::MANAGE_GUILD; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -850,10 +853,10 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`GuildPrune`]: struct.GuildPrune.html /// [`Member`]: struct.Member.html /// [Kick Members]: permissions/constant.KICK_MEMBERS.html @@ -863,7 +866,7 @@ impl Guild { let req = permissions::KICK_MEMBERS; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -880,7 +883,7 @@ impl Guild { /// total, consider using [`utils::shard_id`]. /// /// [`utils::shard_id`]: ../utils/fn.shard_id.html - #[cfg(feature="cache")] + #[cfg(all(feature="cache", feature="utils"))] #[inline] pub fn shard_id(&self) -> u64 { self.id.shard_id() @@ -906,7 +909,7 @@ impl Guild { /// /// assert_eq!(guild.shard_id(17), 7); /// ``` - #[cfg(not(feature="cache"))] + #[cfg(all(feature="utils", not(feature="cache")))] #[inline] pub fn shard_id(&self, shard_count: u64) -> u64 { self.id.shard_id(shard_count) @@ -936,10 +939,10 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`GuildPrune`]: struct.GuildPrune.html /// [`Member`]: struct.Member.html /// [Kick Members]: permissions/constant.KICK_MEMBERS.html @@ -949,7 +952,7 @@ impl Guild { let req = permissions::KICK_MEMBERS; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -962,10 +965,10 @@ impl Guild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html pub fn unban<U: Into<UserId>>(&self, user_id: U) -> Result<()> { @@ -974,7 +977,7 @@ impl Guild { let req = permissions::BAN_MEMBERS; if !self.has_perms(req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } @@ -1258,6 +1261,7 @@ pub struct GuildInfo { pub permissions: Permissions, } +#[cfg(any(feature="model", feature="utils"))] impl GuildInfo { /// Returns the formatted URL of the guild's icon, if the guild has an icon. pub fn icon_url(&self) -> Option<String> { @@ -1284,6 +1288,7 @@ impl From<u64> for GuildContainer { } } +#[cfg(feature="model")] impl InviteGuild { /// Returns the formatted URL of the guild's splash image, if one exists. pub fn splash_url(&self) -> Option<String> { @@ -1314,6 +1319,7 @@ pub enum GuildStatus { Offline(GuildUnavailable), } +#[cfg(feature="model")] impl GuildStatus { /// Retrieves the Id of the inner [`Guild`]. /// diff --git a/src/model/guild/partial_guild.rs b/src/model/guild/partial_guild.rs index 3635a7a..780a6ca 100644 --- a/src/model/guild/partial_guild.rs +++ b/src/model/guild/partial_guild.rs @@ -1,6 +1,8 @@ use super::super::utils::{deserialize_emojis, deserialize_roles}; use ::model::*; -use ::utils::builder::{EditGuild, EditMember, EditRole}; + +#[cfg(feature="model")] +use ::builder::{EditGuild, EditMember, EditRole}; /// Partial information about a [`Guild`]. This does not include information /// like member data. @@ -28,6 +30,7 @@ pub struct PartialGuild { pub verification_level: VerificationLevel, } +#[cfg(feature="model")] impl PartialGuild { /// Ban a [`User`] from the guild. All messages by the /// user within the last given number of days given will be deleted. This @@ -46,15 +49,15 @@ impl PartialGuild { /// /// # Errors /// - /// Returns a [`ClientError::DeleteMessageDaysAmount`] if the number of + /// Returns a [`ModelError::DeleteMessageDaysAmount`] if the number of /// days' worth of messages to delete is over the maximum. /// - /// [`ClientError::DeleteMessageDaysAmount`]: ../client/enum.ClientError.html#variant.DeleteMessageDaysAmount + /// [`ModelError::DeleteMessageDaysAmount`]: enum.ModelError.html#variant.DeleteMessageDaysAmount /// [`User`]: struct.User.html /// [Ban Members]: permissions/constant.BAN_MEMBERS.html pub fn ban<U: Into<UserId>>(&self, user: U, delete_message_days: u8) -> Result<()> { if delete_message_days > 7 { - return Err(Error::Client(ClientError::DeleteMessageDaysAmount(delete_message_days))); + return Err(Error::Model(ModelError::DeleteMessageDaysAmount(delete_message_days))); } self.id.ban(user, delete_message_days) @@ -80,7 +83,7 @@ impl PartialGuild { /// Creates a [`GuildChannel`] in the guild. /// - /// Refer to [`rest::create_channel`] for more information. + /// Refer to [`http::create_channel`] for more information. /// /// Requires the [Manage Channels] permission. /// @@ -95,7 +98,7 @@ impl PartialGuild { /// ``` /// /// [`GuildChannel`]: struct.GuildChannel.html - /// [`rest::create_channel`]: ../client/rest/fn.create_channel.html + /// [`http::create_channel`]: ../http/fn.create_channel.html /// [Manage Channels]: permissions/constant.MANAGE_CHANNELS.html #[inline] pub fn create_channel(&self, name: &str, kind: ChannelType) -> Result<GuildChannel> { @@ -115,7 +118,7 @@ impl PartialGuild { /// how to read an image from the filesystem and encode it as base64. Most /// of the example can be applied similarly for this method. /// - /// [`EditProfile::avatar`]: ../utils/builder/struct.EditProfile.html#method.avatar + /// [`EditProfile::avatar`]: ../builder/struct.EditProfile.html#method.avatar /// [`Guild::create_emoji`]: struct.Guild.html#method.create_emoji /// [`utils::read_image`]: ../utils/fn.read_image.html /// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html @@ -143,10 +146,10 @@ impl PartialGuild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to perform bans. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Guild::create_role`]: struct.Guild.html#method.create_role /// [Manage Roles]: permissions/constant.MANAGE_ROLES.html #[inline] @@ -274,11 +277,11 @@ impl PartialGuild { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have permission to change their own /// nickname. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Change Nickname]: permissions/constant.CHANGE_NICKNAME.html #[inline] pub fn edit_nickname(&self, new_nickname: Option<&str>) -> Result<()> { @@ -407,7 +410,7 @@ impl PartialGuild { /// total, consider using [`utils::shard_id`]. /// /// [`utils::shard_id`]: ../utils/fn.shard_id.html - #[cfg(feature="cache")] + #[cfg(all(feature="cache", feature="utils"))] #[inline] pub fn shard_id(&self) -> u64 { self.id.shard_id() @@ -433,7 +436,7 @@ impl PartialGuild { /// /// assert_eq!(guild.shard_id(17), 7); /// ``` - #[cfg(not(feature="cache"))] + #[cfg(all(feature="utils", not(feature="cache")))] #[inline] pub fn shard_id(&self, shard_count: u64) -> u64 { self.id.shard_id(shard_count) diff --git a/src/model/guild/role.rs b/src/model/guild/role.rs index 58f91de..27ae1f9 100644 --- a/src/model/guild/role.rs +++ b/src/model/guild/role.rs @@ -3,11 +3,13 @@ use std::fmt::{Display, Formatter, Result as FmtResult}; use ::model::*; #[cfg(feature="cache")] -use ::client::{CACHE, rest}; +use ::CACHE; #[cfg(feature="cache")] use ::internal::prelude::*; -#[cfg(feature="cache")] -use ::utils::builder::EditRole; +#[cfg(feature="model")] +use ::http; +#[cfg(feature="builder")] +use ::builder::EditRole; /// Information about a role within a guild. A role represents a set of /// permissions, and can be attached to one or multiple users. A role has @@ -21,8 +23,13 @@ pub struct Role { pub id: RoleId, /// The colour of the role. This is an ergonomic representation of the inner /// value. + #[cfg(feature="utils")] #[serde(rename="color")] pub colour: Colour, + /// The colour of the role. + #[cfg(not(feature="utils"))] + #[serde(rename="color")] + pub colour: u32, /// Indicator of whether the role is pinned above lesser roles. /// /// In the client, this causes [`Member`]s in the role to be seen above @@ -55,6 +62,7 @@ pub struct Role { pub position: i64, } +#[cfg(feature="model")] impl Role { /// Deletes the role. /// @@ -64,7 +72,7 @@ impl Role { #[cfg(feature="cache")] #[inline] pub fn delete(&self) -> Result<()> { - rest::delete_role(self.find_guild()?.0, self.id.0) + http::delete_role(self.find_guild()?.0, self.id.0) } /// Edits a [`Role`], optionally setting its new fields. @@ -95,10 +103,10 @@ impl Role { /// /// # Errors /// - /// Returns a [`ClientError::GuildNotFound`] if a guild is not in the cache + /// Returns a [`ModelError::GuildNotFound`] if a guild is not in the cache /// that contains the role. /// - /// [`ClientError::GuildNotFound`]: ../client/enum.ClientError.html#variant.GuildNotFound + /// [`ModelError::GuildNotFound`]: enum.ModelError.html#variant.GuildNotFound #[cfg(feature="cache")] pub fn find_guild(&self) -> Result<GuildId> { for guild in CACHE.read().unwrap().guilds.values() { @@ -109,7 +117,7 @@ impl Role { } } - Err(Error::Client(ClientError::GuildNotFound)) + Err(Error::Model(ModelError::GuildNotFound)) } /// Check that the role has the given permission. @@ -165,6 +173,7 @@ impl PartialOrd for Role { } } +#[cfg(feature="model")] impl RoleId { /// Search the cache for the role. #[cfg(feature="cache")] diff --git a/src/model/invite.rs b/src/model/invite.rs index 054bece..a1c059e 100644 --- a/src/model/invite.rs +++ b/src/model/invite.rs @@ -1,13 +1,12 @@ use super::*; -use ::client::rest; use ::internal::prelude::*; -use ::utils::builder::CreateInvite; -use ::utils; #[cfg(feature="cache")] -use super::permissions; -#[cfg(feature="cache")] -use super::utils as model_utils; +use super::{permissions, utils as model_utils}; +#[cfg(feature="model")] +use ::http; +#[cfg(feature="model")] +use ::builder::CreateInvite; /// Information about an invite code. /// @@ -39,6 +38,7 @@ pub struct Invite { pub guild: InviteGuild, } +#[cfg(feature="model")] impl Invite { /// Creates an invite for a [`GuildChannel`], providing a builder so that /// fields may optionally be set. @@ -50,11 +50,11 @@ impl Invite { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have the required [permission]. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions - /// [`CreateInvite`]: ../utils/builder/struct.CreateInvite.html + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions + /// [`CreateInvite`]: ../builder/struct.CreateInvite.html /// [`GuildChannel`]: struct.GuildChannel.html /// [Create Invite]: permissions/constant.CREATE_INVITE.html /// [permission]: permissions/index.html @@ -67,11 +67,11 @@ impl Invite { let req = permissions::CREATE_INVITE; if !model_utils::user_has_perms(channel_id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } - rest::create_invite(channel_id.0, &f(CreateInvite::default()).0) + http::create_invite(channel_id.0, &f(CreateInvite::default()).0) } /// Deletes the invite. @@ -80,10 +80,10 @@ impl Invite { /// /// # Errors /// - /// If the `cache` is enabled, returns a [`ClientError::InvalidPermissions`] + /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] /// if the current user does not have the required [permission]. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html /// [permission]: permissions/index.html pub fn delete(&self) -> Result<Invite> { @@ -92,16 +92,23 @@ impl Invite { let req = permissions::MANAGE_GUILD; if !model_utils::user_has_perms(self.channel.id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } - rest::delete_invite(&self.code) + http::delete_invite(&self.code) } /// Gets the information about an invite. pub fn get(code: &str, stats: bool) -> Result<Invite> { - rest::get_invite(utils::parse_invite(code), stats) + let mut invite = code; + + #[cfg(feature="utils")] + { + invite = ::utils::parse_invite(invite); + } + + http::get_invite(invite, stats) } /// Returns a URL to use for the invite. @@ -155,6 +162,7 @@ pub struct InviteGuild { pub voice_channel_count: Option<u64>, } +#[cfg(feature="model")] impl InviteGuild { /// Returns the Id of the shard associated with the guild. /// @@ -166,7 +174,7 @@ impl InviteGuild { /// total, consider using [`utils::shard_id`]. /// /// [`utils::shard_id`]: ../utils/fn.shard_id.html - #[cfg(feature="cache")] + #[cfg(all(feature="cache", feature="utils"))] #[inline] pub fn shard_id(&self) -> u64 { self.id.shard_id() @@ -192,7 +200,7 @@ impl InviteGuild { /// /// assert_eq!(guild.shard_id(17), 7); /// ``` - #[cfg(not(feature="cache"))] + #[cfg(all(feature="utils", not(feature="cache")))] #[inline] pub fn shard_id(&self, shard_count: u64) -> u64 { self.id.shard_id(shard_count) @@ -240,22 +248,23 @@ pub struct RichInvite { pub uses: u64, } +#[cfg(feature="model")] impl RichInvite { /// Deletes the invite. /// - /// Refer to [`rest::delete_invite`] for more information. + /// Refer to [`http::delete_invite`] for more information. /// /// **Note**: Requires the [Manage Guild] permission. /// /// # Errors /// /// If the `cache` feature is enabled, then this returns a - /// [`ClientError::InvalidPermissions`] if the current user does not have + /// [`ModelError::InvalidPermissions`] if the current user does not have /// the required [permission]. /// - /// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions + /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions /// [`Invite::delete`]: struct.Invite.html#method.delete - /// [`rest::delete_invite`]: ../client/rest/fn.delete_invite.html + /// [`http::delete_invite`]: ../http/fn.delete_invite.html /// [Manage Guild]: permissions/constant.MANAGE_GUILD.html /// [permission]: permissions/index.html pub fn delete(&self) -> Result<Invite> { @@ -264,11 +273,11 @@ impl RichInvite { let req = permissions::MANAGE_GUILD; if !model_utils::user_has_perms(self.channel.id, req)? { - return Err(Error::Client(ClientError::InvalidPermissions(req))); + return Err(Error::Model(ModelError::InvalidPermissions(req))); } } - rest::delete_invite(&self.code) + http::delete_invite(&self.code) } /// Returns a URL to use for the invite. diff --git a/src/model/misc.rs b/src/model/misc.rs index 5cf3a91..4da3c01 100644 --- a/src/model/misc.rs +++ b/src/model/misc.rs @@ -1,6 +1,8 @@ use std::result::Result as StdResult; use std::str::FromStr; use super::*; + +#[cfg(feature="utils")] use ::utils; /// Allows something - such as a channel or role - to be mentioned in a message. @@ -68,7 +70,7 @@ impl Mentionable for User { } } -#[cfg(feature="cache")] +#[cfg(all(feature="cache", feature="utils"))] impl FromStr for User { type Err = (); @@ -85,6 +87,7 @@ impl FromStr for User { } } +#[cfg(all(feature="model", feature="utils"))] impl FromStr for UserId { type Err = (); @@ -93,7 +96,7 @@ impl FromStr for UserId { } } -#[cfg(feature="cache")] +#[cfg(all(feature="cache", feature="utils"))] impl FromStr for Role { type Err = (); @@ -110,6 +113,7 @@ impl FromStr for Role { } } +#[cfg(all(feature="model", feature="utils"))] impl FromStr for RoleId { type Err = (); @@ -128,6 +132,7 @@ pub struct EmojiIdentifier { pub name: String, } +#[cfg(all(feature="model", feature="utils"))] impl EmojiIdentifier { /// Generates a URL to the emoji's image. #[inline] @@ -136,6 +141,7 @@ impl EmojiIdentifier { } } +#[cfg(all(feature="model", feature="utils"))] impl FromStr for EmojiIdentifier { type Err = (); @@ -144,6 +150,7 @@ impl FromStr for EmojiIdentifier { } } +#[cfg(all(feature="model", feature="utils"))] impl FromStr for ChannelId { type Err = (); @@ -152,7 +159,7 @@ impl FromStr for ChannelId { } } -#[cfg(feature="cache")] +#[cfg(all(feature="cache", feature="model", feature="utils"))] impl FromStr for Channel { type Err = (); diff --git a/src/model/mod.rs b/src/model/mod.rs index 3ea75c6..26c6f42 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -2,16 +2,16 @@ //! ease of use. //! //! Models can optionally have additional helper methods compiled, by enabling -//! the `methods` feature. +//! the `model` feature. //! //! Methods like [`Message::delete`] or [`Webhook::execute`] are provided with //! this feature, which can be shorthands for operations that are otherwise in -//! the [`Context`], or the much lower-level [`rest`] module. +//! the [`Context`], or the much lower-level [`http`] module. //! //! [`Context`]: ../client/struct.Context.html //! [`Message::delete`]: struct.Message.html#method.delete //! [`Webhook::execute`]: struct.Webhook.html#method.execute -//! [`rest`]: ../client/rest/index.html +//! [`http`]: ../http/index.html #[macro_use] mod utils; @@ -20,6 +20,7 @@ pub mod event; pub mod permissions; mod channel; +mod error; mod gateway; mod guild; mod invite; @@ -29,6 +30,7 @@ mod voice; mod webhook; pub use self::channel::*; +pub use self::error::Error as ModelError; pub use self::gateway::*; pub use self::guild::*; pub use self::invite::*; @@ -45,6 +47,8 @@ use std::fmt::{Formatter, Result as FmtResult}; use std::sync::{Arc, RwLock}; use time::Timespec; use ::internal::prelude::*; + +#[cfg(feature="utils")] use ::utils::Colour; fn default_true() -> bool { true } diff --git a/src/model/permissions.rs b/src/model/permissions.rs index b1ba9f9..aeaf664 100644 --- a/src/model/permissions.rs +++ b/src/model/permissions.rs @@ -280,6 +280,7 @@ bitflags! { } } +#[cfg(feature="model")] impl Permissions { /// Shorthand for checking that the set of permissions contains the /// [Add Reactions] permission. diff --git a/src/model/user.rs b/src/model/user.rs index bff101b..9afd080 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -3,15 +3,17 @@ use std::{fmt, mem}; use super::utils::deserialize_u16; use super::*; use time::Timespec; -use ::client::rest::{self, GuildPagination}; use ::internal::prelude::*; use ::model::misc::Mentionable; -use ::utils::builder::EditProfile; #[cfg(feature="cache")] use std::sync::{Arc, RwLock}; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; +#[cfg(feature="model")] +use ::http::{self, GuildPagination}; +#[cfg(feature="model")] +use ::builder::EditProfile; /// Information about the current user. #[derive(Clone, Debug, Deserialize)] @@ -29,6 +31,7 @@ pub struct CurrentUser { pub verified: bool, } +#[cfg(feature="model")] impl CurrentUser { /// Returns the formatted URL of the user's icon, if one exists. /// @@ -63,7 +66,7 @@ impl CurrentUser { /// Change the avatar: /// /// ```rust,ignore - /// use serenity::client::CACHE; + /// use serenity::CACHE; /// /// let avatar = serenity::utils::read_image("./avatar.png").unwrap(); /// @@ -78,7 +81,7 @@ impl CurrentUser { map.insert("email".to_owned(), Value::String(email.clone())); } - match rest::edit_profile(&f(EditProfile(map)).0) { + match http::edit_profile(&f(EditProfile(map)).0) { Ok(new) => { let _ = mem::replace(self, new); @@ -90,7 +93,7 @@ impl CurrentUser { /// Gets a list of guilds that the current user is in. pub fn guilds(&self) -> Result<Vec<GuildInfo>> { - rest::get_guilds(&GuildPagination::After(GuildId(1)), 100) + http::get_guilds(&GuildPagination::After(GuildId(1)), 100) } /// Returns a static formatted URL of the user's icon, if one exists. @@ -213,6 +216,7 @@ pub struct User { pub name: String, } +#[cfg(feature="model")] impl User { /// Returns the formatted URL of the user's icon, if one exists. /// @@ -310,14 +314,14 @@ impl User { "recipient_id": self.id.0, }); - rest::create_private_channel(&map)?.id + http::create_private_channel(&map)?.id } } else { let map = json!({ "recipient_id": self.id.0, }); - rest::create_private_channel(&map)?.id + http::create_private_channel(&map)?.id }}; let map = json!({ @@ -325,7 +329,7 @@ impl User { "tts": false, }); - rest::send_message(private_channel_id.0, &map) + http::send_message(private_channel_id.0, &map) } /// This is an alias of [direct_message]. @@ -353,10 +357,10 @@ impl User { /// # Errors /// /// If the `cache` is enabled, returns a - /// [`ClientError::InvalidOperationAsUser`] if the current user is not a bot + /// [`ModelError::InvalidOperationAsUser`] if the current user is not a bot /// user. /// - /// [`ClientError::InvalidOperationAsUser`]: ../client/enum.ClientError.html#variant.InvalidOperationAsUser + /// [`ModelError::InvalidOperationAsUser`]: enum.ModelError.html#variant.InvalidOperationAsUser #[inline] pub fn get<U: Into<UserId>>(user_id: U) -> Result<User> { user_id.into().get() @@ -381,7 +385,7 @@ impl User { /// [`Guild`]: struct.Guild.html /// [`GuildId`]: struct.GuildId.html /// [`Role`]: struct.Role.html - /// [`Cache`]: ../ext/cache/struct.Cache.html + /// [`Cache`]: ../cache/struct.Cache.html // no-cache would warn on guild_id. pub fn has_role<G, R>(&self, guild: G, role: R) -> bool where G: Into<GuildContainer>, R: Into<RoleId> { @@ -423,6 +427,7 @@ impl fmt::Display for User { } } +#[cfg(feature="model")] impl UserId { /// Creates a direct message channel between the [current user] and the /// user. This can also retrieve the channel if one already exists. @@ -433,7 +438,7 @@ impl UserId { "recipient_id": self.0, }); - rest::create_private_channel(&map) + http::create_private_channel(&map) } /// Search the cache for the user with the Id. @@ -447,7 +452,7 @@ impl UserId { /// **Note**: The current user must be a bot user. #[inline] pub fn get(&self) -> Result<User> { - rest::get_user(self.0) + http::get_user(self.0) } } diff --git a/src/model/utils.rs b/src/model/utils.rs index 4d6b385..f88ecf5 100644 --- a/src/model/utils.rs +++ b/src/model/utils.rs @@ -9,7 +9,7 @@ use ::internal::prelude::*; #[cfg(feature="cache")] use super::permissions::Permissions; #[cfg(feature="cache")] -use ::client::CACHE; +use ::CACHE; pub fn deserialize_emojis<'de, D: Deserializer<'de>>(deserializer: D) -> StdResult<HashMap<EmojiId, Emoji>, D::Error> { @@ -137,14 +137,14 @@ pub fn deserialize_voice_states<'de, D: Deserializer<'de>>(deserializer: D) Ok(voice_states) } -#[cfg(feature="cache")] +#[cfg(all(feature="cache", feature="model"))] pub fn user_has_perms(channel_id: ChannelId, mut permissions: Permissions) -> Result<bool> { let cache = CACHE.read().unwrap(); let current_user = &cache.user; let channel = match cache.channel(channel_id) { Some(channel) => channel, - None => return Err(Error::Client(ClientError::ItemMissing)), + None => return Err(Error::Model(ModelError::ItemMissing)), }; let guild_id = match channel { @@ -159,13 +159,13 @@ pub fn user_has_perms(channel_id: ChannelId, mut permissions: Permissions) -> Re // // Since serenity can't _reasonably_ check and keep track of these, // just assume that all permissions are granted and return `true`. - return Ok(true); + return Ok(true); }, }; let guild = match cache.guild(guild_id) { Some(guild) => guild, - None => return Err(Error::Client(ClientError::ItemMissing)), + None => return Err(Error::Model(ModelError::ItemMissing)), }; let perms = guild.read().unwrap().permissions_for(channel_id, current_user.id); diff --git a/src/model/webhook.rs b/src/model/webhook.rs index 0a2718e..bacfa53 100644 --- a/src/model/webhook.rs +++ b/src/model/webhook.rs @@ -1,9 +1,12 @@ use std::mem; use super::*; -use ::utils::builder::ExecuteWebhook; -use ::client::rest; use ::internal::prelude::*; +#[cfg(feature="model")] +use ::builder::ExecuteWebhook; +#[cfg(feature="model")] +use ::http; + /// A representation of a webhook, which is a low-effort way to post messages to /// channels. They do not necessarily require a bot user or authentication to /// use. @@ -17,7 +20,7 @@ pub struct Webhook { /// /// This can be modified via [`ExecuteWebhook::avatar`]. /// - /// [`ExecuteWebhook::avatar`]: ../utils/builder/struct.ExecuteWebhook.html#method.avatar + /// [`ExecuteWebhook::avatar`]: ../builder/struct.ExecuteWebhook.html#method.avatar pub avatar: Option<String>, /// The Id of the channel that owns the webhook. pub channel_id: ChannelId, @@ -27,7 +30,7 @@ pub struct Webhook { /// /// This can be modified via [`ExecuteWebhook::username`]. /// - /// [`ExecuteWebhook::username`]: ../utils/builder/struct.ExecuteWebhook.html#method.username + /// [`ExecuteWebhook::username`]: ../builder/struct.ExecuteWebhook.html#method.username pub name: Option<String>, /// The webhook's secure token. pub token: String, @@ -37,16 +40,17 @@ pub struct Webhook { pub user: Option<User>, } +#[cfg(feature="model")] impl Webhook { /// Deletes the webhook. /// - /// As this calls the [`rest::delete_webhook_with_token`] function, + /// As this calls the [`http::delete_webhook_with_token`] function, /// authentication is not required. /// - /// [`rest::delete_webhook_with_token`]: ../client/rest/fn.delete_webhook_with_token.html + /// [`http::delete_webhook_with_token`]: ../http/fn.delete_webhook_with_token.html #[inline] pub fn delete(&self) -> Result<()> { - rest::delete_webhook_with_token(self.id.0, &self.token) + http::delete_webhook_with_token(self.id.0, &self.token) } /// @@ -55,9 +59,9 @@ impl Webhook { /// To nullify the avatar, pass `Some("")`. Otherwise, passing `None` will /// not modify the avatar. /// - /// Refer to [`rest::edit_webhook`] for restrictions on editing webhooks. + /// Refer to [`http::edit_webhook`] for httprictions on editing webhooks. /// - /// As this calls the [`rest::edit_webhook_with_token`] function, + /// As this calls the [`http::edit_webhook_with_token`] function, /// authentication is not required. /// /// # Examples @@ -65,12 +69,12 @@ impl Webhook { /// Editing a webhook's name: /// /// ```rust,no_run - /// use serenity::client::rest; + /// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// - /// let mut webhook = rest::get_webhook_with_token(id, token) + /// let mut webhook = http::get_webhook_with_token(id, token) /// .expect("valid webhook"); /// /// let _ = webhook.edit(Some("new name"), None).expect("Error editing"); @@ -79,12 +83,12 @@ impl Webhook { /// Setting a webhook's avatar: /// /// ```rust,no_run - /// use serenity::client::rest; + /// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// - /// let mut webhook = rest::get_webhook_with_token(id, token) + /// let mut webhook = http::get_webhook_with_token(id, token) /// .expect("valid webhook"); /// /// let image = serenity::utils::read_image("./webhook_img.png") @@ -93,8 +97,8 @@ impl Webhook { /// let _ = webhook.edit(None, Some(&image)).expect("Error editing"); /// ``` /// - /// [`rest::edit_webhook`]: ../client/rest/fn.edit_webhook.html - /// [`rest::edit_webhook_with_token`]: ../client/rest/fn.edit_webhook_with_token.html + /// [`http::edit_webhook`]: ../http/fn.edit_webhook.html + /// [`http::edit_webhook_with_token`]: ../http/fn.edit_webhook_with_token.html pub fn edit(&mut self, name: Option<&str>, avatar: Option<&str>) -> Result<()> { if name.is_none() && avatar.is_none() { return Ok(()); @@ -114,7 +118,7 @@ impl Webhook { map.insert("name".to_owned(), Value::String(name.to_owned())); } - match rest::edit_webhook_with_token(self.id.0, &self.token, &map) { + match http::edit_webhook_with_token(self.id.0, &self.token, &map) { Ok(replacement) => { mem::replace(self, replacement); @@ -134,12 +138,12 @@ impl Webhook { /// Execute a webhook with message content of `test`: /// /// ```rust,no_run - /// use serenity::client::rest; + /// use serenity::http; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// - /// let mut webhook = rest::get_webhook_with_token(id, token) + /// let mut webhook = http::get_webhook_with_token(id, token) /// .expect("valid webhook"); /// /// let _ = webhook.execute(|w| w.content("test")).expect("Error executing"); @@ -149,13 +153,13 @@ impl Webhook { /// username to `serenity`, and sending an embed: /// /// ```rust,no_run - /// use serenity::client::rest; + /// use serenity::http; /// use serenity::model::Embed; /// /// let id = 245037420704169985; /// let token = "ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// - /// let mut webhook = rest::get_webhook_with_token(id, token) + /// let mut webhook = http::get_webhook_with_token(id, token) /// .expect("valid webhook"); /// /// let embed = Embed::fake(|e| e @@ -173,18 +177,18 @@ impl Webhook { /// ``` #[inline] pub fn execute<F: FnOnce(ExecuteWebhook) -> ExecuteWebhook>(&self, f: F) -> Result<Message> { - rest::execute_webhook(self.id.0, &self.token, &f(ExecuteWebhook::default()).0) + http::execute_webhook(self.id.0, &self.token, &f(ExecuteWebhook::default()).0) } /// Retrieves the latest information about the webhook, editing the /// webhook in-place. /// - /// As this calls the [`rest::get_webhook_with_token`] function, + /// As this calls the [`http::get_webhook_with_token`] function, /// authentication is not required. /// - /// [`rest::get_webhook_with_token`]: ../client/rest/fn.get_webhook_with_token.html + /// [`http::get_webhook_with_token`]: ../http/fn.get_webhook_with_token.html pub fn refresh(&mut self) -> Result<()> { - match rest::get_webhook_with_token(self.id.0, &self.token) { + match http::get_webhook_with_token(self.id.0, &self.token) { Ok(replacement) => { let _ = mem::replace(self, replacement); @@ -195,6 +199,7 @@ impl Webhook { } } +#[cfg(feature="model")] impl WebhookId { /// Retrieves the webhook by the Id. /// @@ -203,6 +208,6 @@ impl WebhookId { /// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html #[inline] pub fn get(&self) -> Result<Webhook> { - rest::get_webhook(self.0) + http::get_webhook(self.0) } } diff --git a/src/prelude.rs b/src/prelude.rs index 829ea9c..f4e7a2a 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -14,6 +14,8 @@ //! //! [`serenity::Error`]: ../enum.Error.html -pub use ::client::{Client, ClientError as ClientError}; pub use ::error::{Error as SerenityError}; pub use ::model::Mentionable; + +#[cfg(feature="client")] +pub use ::client::{Client, ClientError as ClientError}; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index ec19ff7..6ae937e 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,17 +1,16 @@ //! A set of utilities to help with common use cases that are not required to //! fully use the library. -#[macro_use] -pub mod macros; - -pub mod builder; - mod colour; mod message_builder; pub use self::colour::Colour; +// Note: Here for BC purposes. +#[cfg(feature="builder")] +pub use super::builder; + use base64; use std::ffi::OsStr; use std::fs::File; diff --git a/src/ext/voice/audio.rs b/src/voice/audio.rs index ea8c87a..ea8c87a 100644 --- a/src/ext/voice/audio.rs +++ b/src/voice/audio.rs diff --git a/src/ext/voice/connection.rs b/src/voice/connection.rs index 698f469..698f469 100644 --- a/src/ext/voice/connection.rs +++ b/src/voice/connection.rs diff --git a/src/ext/voice/connection_info.rs b/src/voice/connection_info.rs index d0364ce..d0364ce 100644 --- a/src/ext/voice/connection_info.rs +++ b/src/voice/connection_info.rs diff --git a/src/ext/voice/error.rs b/src/voice/error.rs index 55be1f6..55be1f6 100644 --- a/src/ext/voice/error.rs +++ b/src/voice/error.rs diff --git a/src/ext/voice/handler.rs b/src/voice/handler.rs index 545befe..22c0375 100644 --- a/src/ext/voice/handler.rs +++ b/src/voice/handler.rs @@ -2,8 +2,8 @@ use std::sync::mpsc::{self, Sender as MpscSender}; use super::{AudioReceiver, AudioSource}; use super::connection_info::ConnectionInfo; use super::Status as VoiceStatus; -use ::client::gateway::GatewayStatus; use ::constants::VoiceOpCode; +use ::gateway::GatewayStatus; use ::model::{ChannelId, GuildId, UserId, VoiceState}; use super::threading; @@ -19,8 +19,7 @@ use super::threading; /// # Examples /// /// Assuming that you already have a `Manager`, most likely retrieved via a -/// [WebSocket connection], you can join a guild's voice channel and deafen -/// yourself like so: +/// [`Shard`], you can join a guild's voice channel and deafen yourself like so: /// /// ```rust,ignore /// // assuming a `manager` has already been bound, hopefully retrieved through @@ -35,7 +34,7 @@ use super::threading; /// ``` /// /// [`Manager`]: struct.Manager.html -/// [WebSocket connection]: ../../client/struct.Connection.html +/// [`Shard`]: ../gateway/struct.Shard.html #[derive(Clone, Debug)] pub struct Handler { /// The ChannelId to be connected to, if any. diff --git a/src/ext/voice/manager.rs b/src/voice/manager.rs index e85a5a3..fe1b489 100644 --- a/src/ext/voice/manager.rs +++ b/src/voice/manager.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; use std::sync::mpsc::Sender as MpscSender; use super::Handler; -use ::client::gateway::GatewayStatus; +use ::gateway::GatewayStatus; use ::model::{ChannelId, GuildId, UserId}; /// A manager is a struct responsible for managing [`Handler`]s which belong to -/// a single [WebSocket connection]. This is a fairly complex key-value store, +/// a single [`Shard`]. This is a fairly complex key-value store, /// with a bit of extra utility for easily joining a "target". /// /// The "target" used by the Manager is determined based on the `guild_id` and @@ -19,7 +19,7 @@ use ::model::{ChannelId, GuildId, UserId}; /// [`Group`]: ../../model/struct.Group.html /// [`Handler`]: struct.Handler.html /// [guild's channel]: ../../model/enum.ChannelType.html#variant.Voice -/// [WebSocket connection]: ../../client/struct.Connection.html +/// [`Shard`]: ../gateway/struct.Shard.html #[derive(Clone, Debug)] pub struct Manager { handlers: HashMap<GuildId, Handler>, diff --git a/src/ext/voice/mod.rs b/src/voice/mod.rs index 94e3b40..94e3b40 100644 --- a/src/ext/voice/mod.rs +++ b/src/voice/mod.rs diff --git a/src/ext/voice/payload.rs b/src/voice/payload.rs index c2e7c0c..c2e7c0c 100644 --- a/src/ext/voice/payload.rs +++ b/src/voice/payload.rs diff --git a/src/ext/voice/streamer.rs b/src/voice/streamer.rs index 4d3b9a9..4d3b9a9 100644 --- a/src/ext/voice/streamer.rs +++ b/src/voice/streamer.rs diff --git a/src/ext/voice/threading.rs b/src/voice/threading.rs index 4777231..4777231 100644 --- a/src/ext/voice/threading.rs +++ b/src/voice/threading.rs |