aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2017-05-22 17:02:00 -0700
committerZeyla Hellyer <[email protected]>2017-05-22 17:02:00 -0700
commit9969be60cf320797c37b317da24d9a08fd5eafa5 (patch)
treef27bf7a57af95bbc11990b1edcea9cca99276964
parentReasonably derive Debug on items (diff)
downloadserenity-9969be60cf320797c37b317da24d9a08fd5eafa5.tar.xz
serenity-9969be60cf320797c37b317da24d9a08fd5eafa5.zip
Restructure modules
Modules are now separated into a fashion where the library can be used for most use cases, without needing to compile the rest. The core of serenity, with no features enabled, contains only the struct (model) definitions, constants, and prelude. Models do not have most functions compiled in, as that is separated into the `model` feature. The `client` module has been split into 3 modules: `client`, `gateway`, and `http`. `http` contains functions to interact with the REST API. `gateway` contains the Shard to interact with the gateway, requiring `http` for retrieving the gateway URL. `client` requires both of the other features and acts as an abstracted interface over both the gateway and REST APIs, handling the event loop. The `builder` module has been separated from `utils`, and can now be optionally compiled in. It and the `http` feature are required by the `model` feature due to a large number of methods requiring access to them. `utils` now contains a number of utilities, such as the Colour struct, the `MessageBuilder`, and mention parsing functions. Each of the original `ext` modules are still featured, with `cache` not requiring any feature to be enabled, `framework` requiring the `client`, `model`, and `utils`, and `voice` requiring `gateway`. In total the features and their requirements are: - `builder`: none - `cache`: none - `client`: `gateway`, `http` - `framework`: `client`, `model`, `utils` - `gateway`: `http` - `http`: none - `model`: `builder`, `http` - `utils`: none - `voice`: `gateway` The default features are `builder`, `cache`, `client`, `framework`, `gateway`, `model`, `http`, and `utils`. To help with forwards compatibility, modules have been re-exported from their original locations.
-rw-r--r--Cargo.toml45
-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.rs18
-rw-r--r--src/client/dispatch.rs2
-rw-r--r--src/client/error.rs149
-rw-r--r--src/client/mod.rs89
-rw-r--r--src/constants.rs49
-rw-r--r--src/error.rs96
-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.rs35
-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.rs5
-rw-r--r--src/internal/prelude.rs4
-rw-r--r--src/internal/ws_impl.rs2
-rw-r--r--src/lib.rs100
-rw-r--r--src/model/channel/attachment.rs2
-rw-r--r--src/model/channel/channel_id.rs87
-rw-r--r--src/model/channel/embed.rs14
-rw-r--r--src/model/channel/group.rs36
-rw-r--r--src/model/channel/guild_channel.rs73
-rw-r--r--src/model/channel/message.rs84
-rw-r--r--src/model/channel/mod.rs35
-rw-r--r--src/model/channel/private_channel.rs27
-rw-r--r--src/model/channel/reaction.rs21
-rw-r--r--src/model/error.rs109
-rw-r--r--src/model/event.rs8
-rw-r--r--src/model/gateway.rs1
-rw-r--r--src/model/guild/emoji.rs17
-rw-r--r--src/model/guild/guild_id.rs87
-rw-r--r--src/model/guild/member.rs57
-rw-r--r--src/model/guild/mod.rs98
-rw-r--r--src/model/guild/partial_guild.rs29
-rw-r--r--src/model/guild/role.rs23
-rw-r--r--src/model/invite.rs57
-rw-r--r--src/model/misc.rs13
-rw-r--r--src/model/mod.rs10
-rw-r--r--src/model/permissions.rs1
-rw-r--r--src/model/user.rs33
-rw-r--r--src/model/utils.rs10
-rw-r--r--src/model/webhook.rs55
-rw-r--r--src/prelude.rs4
-rw-r--r--src/utils/mod.rs9
-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
diff --git a/Cargo.toml b/Cargo.toml
index 0a43713..ee00139 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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 {
diff --git a/src/lib.rs b/src/lib.rs
index 793ad12..50c5d37 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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