aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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