aboutsummaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2018-08-05 11:07:21 -0700
committerZeyla Hellyer <[email protected]>2018-08-05 11:07:21 -0700
commitbbbf63868a8ef3c0f21c1896f7afb96f4d8fbcc1 (patch)
treea04c4f18f56d5c5d34a7c2e31de52c1cb87966de /src/http
parentMake http::wind perform requests (diff)
downloadserenity-bbbf63868a8ef3c0f21c1896f7afb96f4d8fbcc1.tar.xz
serenity-bbbf63868a8ef3c0f21c1896f7afb96f4d8fbcc1.zip
[http] Abstract out routing methods and paths
Diffstat (limited to 'src/http')
-rw-r--r--src/http/mod.rs632
-rw-r--r--src/http/ratelimiting.rs283
-rw-r--r--src/http/routing.rs1433
3 files changed, 1694 insertions, 654 deletions
diff --git a/src/http/mod.rs b/src/http/mod.rs
index ff01cb4..b3af412 100644
--- a/src/http/mod.rs
+++ b/src/http/mod.rs
@@ -24,6 +24,7 @@
//! [model]: ../model/index.html
pub mod ratelimiting;
+pub mod routing;
mod error;
@@ -39,7 +40,7 @@ use hyper::{
Request as HyperRequest,
Response as HyperResponse
},
- header::{ContentType, Headers},
+ header::{Authorization, ContentType, Headers, UserAgent},
method::Method,
mime::{Mime, SubLevel, TopLevel},
net::HttpsConnector,
@@ -53,13 +54,12 @@ use internal::prelude::*;
use model::prelude::*;
use multipart::client::Multipart;
use parking_lot::Mutex;
-use self::ratelimiting::Route;
+use self::routing::RouteInfo;
use serde::de::DeserializeOwned;
use serde_json;
use std::{
collections::BTreeMap,
default::Default,
- fmt::Write as FmtWrite,
fs::File,
io::ErrorKind as IoErrorKind,
path::{Path, PathBuf},
@@ -75,12 +75,42 @@ lazy_static! {
};
}
-struct Request {
- body: Option<Vec<u8>>,
+#[derive(Clone, Debug)]
+struct Request<'a> {
+ body: Option<&'a [u8]>,
headers: Option<Headers>,
- method: Method,
- route: Route,
- url: String,
+ route: RouteInfo<'a>,
+}
+
+impl<'a> Request<'a> {
+ fn build(&'a self) -> RequestBuilder<'a> {
+ let Request {
+ body,
+ headers: request_headers,
+ route: route_info,
+ } = self;
+ let (method, _, path) = route_info.deconstruct();
+
+ let mut builder = CLIENT.request(
+ method.hyper_method(),
+ &path.into_owned(),
+ );
+
+ if let Some(bytes) = body {
+ builder = builder.body(HyperBody::BufBody(bytes, bytes.len()));
+ }
+
+ let mut headers = Headers::new();
+ headers.set(UserAgent(constants::USER_AGENT.to_string()));
+ headers.set(Authorization(TOKEN.lock().clone()));
+ headers.set(ContentType::json());
+
+ if let Some(request_headers) = request_headers.clone() {
+ headers.extend(request_headers.iter());
+ }
+
+ builder.headers(headers)
+ }
}
/// An method used for ratelimiting special routes.
@@ -88,8 +118,6 @@ struct Request {
/// This is needed because `hyper`'s `Method` enum does not derive Copy.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum LightMethod {
- /// Indicates that a route is for "any" method.
- Any,
/// Indicates that a route is for the `DELETE` method only.
Delete,
/// Indicates that a route is for the `GET` method only.
@@ -102,6 +130,18 @@ pub enum LightMethod {
Put,
}
+impl LightMethod {
+ pub fn hyper_method(&self) -> Method {
+ match *self {
+ LightMethod::Delete => Method::Delete,
+ LightMethod::Get => Method::Get,
+ LightMethod::Patch => Method::Patch,
+ LightMethod::Post => Method::Post,
+ LightMethod::Put => Method::Put,
+ }
+ }
+}
+
lazy_static! {
static ref TOKEN: Arc<Mutex<String>> = Arc::new(Mutex::new(String::default()));
}
@@ -143,9 +183,7 @@ pub fn add_group_recipient(group_id: u64, user_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Put,
- route: Route::None,
- url: api!("/channels/{}/recipients/{}", group_id, user_id),
+ route: RouteInfo::AddGroupRecipient { group_id, user_id },
})
}
@@ -162,9 +200,7 @@ pub fn add_member_role(guild_id: u64, user_id: u64, role_id: u64) -> Result<()>
wind(204, Request {
body: None,
headers: None,
- method: Method::Put,
- route: Route::GuildsIdMembersIdRolesId(guild_id),
- url: api!("/guilds/{}/members/{}/roles/{}", guild_id, user_id, role_id),
+ route: RouteInfo::AddMemberRole { guild_id, role_id, user_id },
})
}
@@ -183,15 +219,12 @@ pub fn ban_user(guild_id: u64, user_id: u64, delete_message_days: u8, reason: &s
wind(204, Request {
body: None,
headers: None,
- method: Method::Put,
- route: Route::GuildsIdBansUserId(guild_id),
- url: api!(
- "/guilds/{}/bans/{}?delete_message_days={}&reason={}",
+ route: RouteInfo::GuildBanUser {
+ delete_message_days: Some(delete_message_days),
+ reason: Some(reason),
guild_id,
user_id,
- delete_message_days,
- reason,
- ),
+ },
})
}
@@ -251,9 +284,7 @@ pub fn broadcast_typing(channel_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Post,
- route: Route::ChannelsIdTyping(channel_id),
- url: api!("/channels/{}/typing", channel_id),
+ route: RouteInfo::BroadcastTyping { channel_id },
})
}
@@ -269,11 +300,9 @@ pub fn broadcast_typing(channel_id: u64) -> Result<()> {
/// [Manage Channels]: ../model/permissions/constant.MANAGE_CHANNELS.html
pub fn create_channel(guild_id: u64, map: &Value) -> Result<GuildChannel> {
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(map.to_string().as_bytes()),
headers: None,
- method: Method::Post,
- route: Route::GuildsIdChannels(guild_id),
- url: api!("/guilds/{}/channels", guild_id),
+ route: RouteInfo::CreateChannel { guild_id },
})
}
@@ -289,11 +318,9 @@ pub fn create_channel(guild_id: u64, map: &Value) -> Result<GuildChannel> {
/// [Manage Emojis]: ../model/permissions/constant.MANAGE_EMOJIS.html
pub fn create_emoji(guild_id: u64, map: &Value) -> Result<Emoji> {
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(map.to_string().as_bytes()),
headers: None,
- method: Method::Post,
- route: Route::GuildsIdEmojis(guild_id),
- url: api!("/guilds/{}/emojis", guild_id),
+ route: RouteInfo::CreateEmoji { guild_id },
})
}
@@ -335,11 +362,9 @@ pub fn create_emoji(guild_id: u64, map: &Value) -> Result<Emoji> {
/// [whitelist]: https://discordapp.com/developers/docs/resources/guild#create-guild
pub fn create_guild(map: &Value) -> Result<PartialGuild> {
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(map.to_string().as_bytes()),
headers: None,
- method: Method::Post,
- route: Route::Guilds,
- url: api!("/guilds").to_owned(),
+ route: RouteInfo::CreateGuild,
})
}
@@ -355,11 +380,9 @@ pub fn create_guild(map: &Value) -> Result<PartialGuild> {
/// [docs]: https://discordapp.com/developers/docs/resources/guild#create-guild-integration
pub fn create_guild_integration(guild_id: u64, integration_id: u64, map: &Value) -> Result<()> {
wind(204, Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(map.to_string().as_bytes()),
headers: None,
- method: Method::Post,
- route: Route::GuildsIdIntegrations(guild_id),
- url: api!("/guilds/{}/integrations/{}", guild_id, integration_id),
+ route: RouteInfo::CreateGuildIntegration { guild_id, integration_id },
})
}
@@ -379,33 +402,31 @@ pub fn create_invite(channel_id: u64, map: &JsonMap) -> Result<RichInvite> {
let body = serde_json::to_vec(map)?;
fire(Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Post,
- route: Route::ChannelsIdInvites(channel_id),
- url: api!("/channels/{}/invites", channel_id),
+ route: RouteInfo::CreateInvite { channel_id },
})
}
/// Creates a permission override for a member or a role in a channel.
pub fn create_permission(channel_id: u64, target_id: u64, map: &Value) -> Result<()> {
+ let body = serde_json::to_vec(map)?;
+
wind(204, Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Put,
- route: Route::ChannelsIdPermissionsOverwriteId(channel_id),
- url: api!("/channels/{}/permissions/{}", channel_id, target_id),
+ route: RouteInfo::CreatePermission { channel_id, target_id },
})
}
/// Creates a private channel with a user.
pub fn create_private_channel(map: &Value) -> Result<PrivateChannel> {
+ let body = serde_json::to_vec(map)?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Post,
- route: Route::UsersMeChannels,
- url: api!("/users/@me/channels").to_owned(),
+ route: RouteInfo::GetUserDmChannels,
})
}
@@ -417,14 +438,11 @@ pub fn create_reaction(channel_id: u64,
wind(204, Request {
body: None,
headers: None,
- method: Method::Put,
- route: Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
- url: api!(
- "/channels/{}/messages/{}/reactions/{}/@me",
+ route: RouteInfo::CreateReaction {
+ reaction: &reaction_type.as_data(),
channel_id,
message_id,
- reaction_type.as_data(),
- ),
+ },
})
}
@@ -433,11 +451,9 @@ pub fn create_role(guild_id: u64, map: &JsonMap) -> Result<Role> {
let body = serde_json::to_vec(map)?;
fire(Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Post,
- route: Route::GuildsIdRoles(guild_id),
- url: api!("/guilds/{}/roles", guild_id),
+ route: RouteInfo::CreateRole {guild_id },
})
}
@@ -472,12 +488,12 @@ pub fn create_role(guild_id: u64, map: &JsonMap) -> Result<Role> {
///
/// [`GuildChannel`]: ../model/channel/struct.GuildChannel.html
pub fn create_webhook(channel_id: u64, map: &Value) -> Result<Webhook> {
+ let body = serde_json::to_vec(map)?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Post,
- route: Route::ChannelsIdWebhooks(channel_id),
- url: api!("/channels/{}/webhooks", channel_id),
+ route: RouteInfo::CreateWebhook { channel_id },
})
}
@@ -486,9 +502,7 @@ pub fn delete_channel(channel_id: u64) -> Result<Channel> {
fire(Request {
body: None,
headers: None,
- route: Route::ChannelsId(channel_id),
- method: Method::Delete,
- url: api!("/channels/{}", channel_id),
+ route: RouteInfo::DeleteChannel { channel_id },
})
}
@@ -497,9 +511,7 @@ pub fn delete_emoji(guild_id: u64, emoji_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::GuildsIdEmojisId(guild_id),
- url: api!("/guilds/{}/emojis/{}", guild_id, emoji_id),
+ route: RouteInfo::DeleteEmoji { guild_id, emoji_id },
})
}
@@ -508,9 +520,7 @@ pub fn delete_guild(guild_id: u64) -> Result<PartialGuild> {
fire(Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::GuildsId(guild_id),
- url: api!("/guilds/{}", guild_id),
+ route: RouteInfo::DeleteGuild { guild_id },
})
}
@@ -519,9 +529,7 @@ pub fn delete_guild_integration(guild_id: u64, integration_id: u64) -> Result<()
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::GuildsIdIntegrationsId(guild_id),
- url: api!("/guilds/{}/integrations/{}", guild_id, integration_id),
+ route: RouteInfo::DeleteGuildIntegration { guild_id, integration_id },
})
}
@@ -530,9 +538,7 @@ pub fn delete_invite(code: &str) -> Result<Invite> {
fire(Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::InvitesCode,
- url: api!("/invites/{}", code),
+ route: RouteInfo::DeleteInvite { code },
})
}
@@ -542,20 +548,16 @@ pub fn delete_message(channel_id: u64, message_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::ChannelsIdMessagesId(LightMethod::Delete, channel_id),
- url: api!("/channels/{}/messages/{}", channel_id, message_id),
+ route: RouteInfo::DeleteMessage { channel_id, message_id },
})
}
/// Deletes a bunch of messages, only works for bots.
pub fn delete_messages(channel_id: u64, map: &Value) -> Result<()> {
wind(204, Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(map.to_string().as_bytes()),
headers: None,
- method: Method::Delete,
- route: Route::ChannelsIdMessagesBulkDelete(channel_id),
- url: api!("/channels/{}/messages/bulk-delete", channel_id),
+ route: RouteInfo::DeleteMessages { channel_id },
})
}
@@ -580,9 +582,7 @@ pub fn delete_message_reactions(channel_id: u64, message_id: u64) -> Result<()>
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::ChannelsIdMessagesIdReactions(channel_id),
- url: api!("/channels/{}/messages/{}/reactions", channel_id, message_id),
+ route: RouteInfo::DeleteMessageReactions { channel_id, message_id },
})
}
@@ -591,9 +591,7 @@ pub fn delete_permission(channel_id: u64, target_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::ChannelsIdPermissionsOverwriteId(channel_id),
- url: api!("/channels/{}/permissions/{}", channel_id, target_id),
+ route: RouteInfo::DeletePermission { channel_id, target_id },
})
}
@@ -611,15 +609,12 @@ pub fn delete_reaction(channel_id: u64,
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
- url: api!(
- "/channels/{}/messages/{}/reactions/{}/{}",
+ route: RouteInfo::DeleteReaction {
+ reaction: &reaction_type.as_data(),
+ user: &user,
channel_id,
message_id,
- reaction_type.as_data(),
- user,
- ),
+ },
})
}
@@ -628,9 +623,7 @@ pub fn delete_role(guild_id: u64, role_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::GuildsIdRolesId(guild_id),
- url: api!("/guilds/{}/roles/{}", guild_id, role_id),
+ route: RouteInfo::DeleteRole { guild_id, role_id },
})
}
@@ -660,9 +653,7 @@ pub fn delete_webhook(webhook_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::WebhooksId(webhook_id),
- url: api!("/webhooks/{}", webhook_id),
+ route: RouteInfo::DeleteWebhook { webhook_id },
})
}
@@ -688,9 +679,7 @@ pub fn delete_webhook_with_token(webhook_id: u64, token: &str) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::None,
- url: api!("/webhooks/{}/{}", webhook_id, token),
+ route: RouteInfo::DeleteWebhookWithToken { token, webhook_id },
})
}
@@ -699,22 +688,20 @@ pub fn edit_channel(channel_id: u64, map: &JsonMap) -> Result<GuildChannel> {
let body = serde_json::to_vec(map)?;
fire(Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::ChannelsId(channel_id),
- url: api!("/channels/{}", channel_id),
+ route: RouteInfo::EditChannel {channel_id },
})
}
/// Changes emoji information.
pub fn edit_emoji(guild_id: u64, emoji_id: u64, map: &Value) -> Result<Emoji> {
+ let body = serde_json::to_vec(map)?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsIdEmojisId(guild_id),
- url: api!("/guilds/{}/emojis/{}", guild_id, emoji_id),
+ route: RouteInfo::EditEmoji { guild_id, emoji_id },
})
}
@@ -723,23 +710,21 @@ pub fn edit_guild(guild_id: u64, map: &JsonMap) -> Result<PartialGuild> {
let body = serde_json::to_vec(map)?;
fire(Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsId(guild_id),
- url: api!("/guilds/{}", guild_id),
+ route: RouteInfo::EditGuild { guild_id },
})
}
/// Edits the positions of a guild's channels.
pub fn edit_guild_channel_positions(guild_id: u64, value: &Value)
-> Result<()> {
+ let body = serde_json::to_vec(value)?;
+
wind(204, Request {
- body: Some(value.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsIdChannels(guild_id),
- url: api!("/guilds/{}/channels", guild_id),
+ route: RouteInfo::EditGuildChannels { guild_id },
})
}
@@ -747,12 +732,12 @@ pub fn edit_guild_channel_positions(guild_id: u64, value: &Value)
///
/// [`Guild`]: ../model/guild/struct.Guild.html
pub fn edit_guild_embed(guild_id: u64, map: &Value) -> Result<GuildEmbed> {
+ let body = serde_json::to_vec(map)?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsIdEmbed(guild_id),
- url: api!("/guilds/{}/embed", guild_id),
+ route: RouteInfo::EditGuildEmbed { guild_id },
})
}
@@ -761,11 +746,9 @@ pub fn edit_member(guild_id: u64, user_id: u64, map: &JsonMap) -> Result<()> {
let body = serde_json::to_vec(map)?;
wind(204, Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsIdMembersId(guild_id),
- url: api!("/guilds/{}/members/{}", guild_id, user_id),
+ route: RouteInfo::EditMember { guild_id, user_id },
})
}
@@ -773,12 +756,12 @@ pub fn edit_member(guild_id: u64, user_id: u64, map: &JsonMap) -> Result<()> {
///
/// **Note**: Only the author of a message can modify it.
pub fn edit_message(channel_id: u64, message_id: u64, map: &Value) -> Result<Message> {
+ let body = serde_json::to_vec(map)?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::ChannelsIdMessagesId(LightMethod::Any, channel_id),
- url: api!("/channels/{}/messages/{}", channel_id, message_id),
+ route: RouteInfo::EditMessage { channel_id, message_id },
})
}
@@ -789,13 +772,12 @@ pub fn edit_message(channel_id: u64, message_id: u64, map: &Value) -> Result<Mes
/// [`Guild`]: ../model/guild/struct.Guild.html
pub fn edit_nickname(guild_id: u64, new_nickname: Option<&str>) -> Result<()> {
let map = json!({ "nick": new_nickname });
+ let body = serde_json::to_vec(&map)?;
wind(200, Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsIdMembersMeNick(guild_id),
- url: api!("/guilds/{}/members/@me/nick", guild_id),
+ route: RouteInfo::EditNickname { guild_id },
})
}
@@ -815,11 +797,9 @@ pub fn edit_profile(map: &JsonMap) -> Result<CurrentUser> {
let body = serde_json::to_vec(map)?;
let response = request(Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::UsersMe,
- url: api!("/users/@me").to_owned(),
+ route: RouteInfo::EditProfile,
})?;
let mut value = serde_json::from_reader::<HyperResponse, Value>(response)?;
@@ -840,27 +820,23 @@ pub fn edit_role(guild_id: u64, role_id: u64, map: &JsonMap) -> Result<Role> {
let body = serde_json::to_vec(&map)?;
fire(Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsIdRolesId(guild_id),
- url: api!("/guilds/{}/roles/{}", guild_id, role_id),
+ route: RouteInfo::EditRole { guild_id, role_id },
})
}
/// Changes the position of a role in a guild.
pub fn edit_role_position(guild_id: u64, role_id: u64, position: u64) -> Result<Vec<Role>> {
- let body = serde_json::to_string(&json!({
+ let body = serde_json::to_vec(&json!({
"id": role_id,
"position": position,
}))?;
fire(Request {
- body: Some(body.into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::GuildsIdRolesId(guild_id),
- url: api!("/guilds/{}/roles/{}", guild_id, role_id),
+ route: RouteInfo::EditRole { guild_id, role_id },
})
}
@@ -905,11 +881,9 @@ pub fn edit_role_position(guild_id: u64, role_id: u64, position: u64) -> Result<
// external crates being incredibly messy and misleading in the end user's view.
pub fn edit_webhook(webhook_id: u64, map: &Value) -> Result<Webhook> {
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(map.to_string().as_bytes()),
headers: None,
- method: Method::Patch,
- route: Route::WebhooksId(webhook_id),
- url: api!("/webhooks/{}", webhook_id),
+ route: RouteInfo::EditWebhook { webhook_id },
})
}
@@ -943,11 +917,9 @@ pub fn edit_webhook_with_token(webhook_id: u64, token: &str, map: &JsonMap) -> R
let body = serde_json::to_vec(map)?;
fire(Request {
- body: Some(body),
+ body: Some(&body),
headers: None,
- method: Method::Patch,
- route: Route::None,
- url: api!("/webhooks/{}/{}", webhook_id, token),
+ route: RouteInfo::EditWebhookWithToken { token, webhook_id },
})
}
@@ -1024,11 +996,9 @@ pub fn execute_webhook(webhook_id: u64,
));
let response = request(Request {
- body: Some(body),
+ body: Some(&body),
headers: Some(headers),
- method: Method::Get,
- route: Route::None,
- url: api!("/webhooks/{}/{}?wait={}", webhook_id, token, wait),
+ route: RouteInfo::ExecuteWebhook { token, wait, webhook_id },
})?;
if response.status == StatusCode::NoContent {
@@ -1047,9 +1017,7 @@ pub fn get_active_maintenances() -> Result<Vec<Maintenance>> {
let response = request(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::None,
- url: status!("/scheduled-maintenances/active.json").to_owned(),
+ route: RouteInfo::GetActiveMaintenance,
})?;
let mut map: BTreeMap<String, Value> = serde_json::from_reader(response)?;
@@ -1066,9 +1034,7 @@ pub fn get_bans(guild_id: u64) -> Result<Vec<Ban>> {
fire(Request {
body: None,
headers: None,
- route: Route::GuildsIdBans(guild_id),
- method: Method::Get,
- url: api!("/guilds/{}/bans", guild_id),
+ route: RouteInfo::GetBans { guild_id },
})
}
@@ -1078,32 +1044,16 @@ pub fn get_audit_logs(guild_id: u64,
user_id: Option<u64>,
before: Option<u64>,
limit: Option<u8>) -> Result<AuditLogs> {
- let mut params = Vec::with_capacity(4);
-
- if let Some(action_type) = action_type {
- params.push(format!("action_type={}", action_type));
- }
- if let Some(user_id) = user_id {
- params.push(format!("user_id={}", user_id));
- }
- if let Some(before) = before {
- params.push(format!("before={}", before));
- }
- if let Some(limit) = limit {
- params.push(format!("limit={}", limit));
- }
-
- let mut query_string = params.join("&");
- if !query_string.is_empty() {
- query_string.insert(0, '?');
- }
-
fire(Request {
body: None,
headers: None,
- route: Route::GuildsIdAuditLogs(guild_id),
- method: Method::Get,
- url: api!("/guilds/{}/audit-logs{}", guild_id, query_string),
+ route: RouteInfo::GetAuditLogs {
+ action_type,
+ before,
+ guild_id,
+ limit,
+ user_id,
+ },
})
}
@@ -1112,9 +1062,7 @@ pub fn get_bot_gateway() -> Result<BotGateway> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GatewayBot,
- url: api!("/gateway/bot").to_owned(),
+ route: RouteInfo::GetBotGateway,
})
}
@@ -1123,9 +1071,7 @@ pub fn get_channel_invites(channel_id: u64) -> Result<Vec<RichInvite>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::ChannelsIdInvites(channel_id),
- url: api!("/channels/{}/invites", channel_id),
+ route: RouteInfo::GetChannelInvites { channel_id },
})
}
@@ -1151,9 +1097,7 @@ pub fn get_channel_webhooks(channel_id: u64) -> Result<Vec<Webhook>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::ChannelsIdWebhooks(channel_id),
- url: api!("/channels/{}/webhooks", channel_id),
+ route: RouteInfo::GetChannelWebhooks { channel_id },
})
}
@@ -1162,9 +1106,7 @@ pub fn get_channel(channel_id: u64) -> Result<Channel> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::ChannelsId(channel_id),
- url: api!("/channels/{}", channel_id),
+ route: RouteInfo::GetChannel { channel_id },
})
}
@@ -1173,9 +1115,7 @@ pub fn get_channels(guild_id: u64) -> Result<Vec<GuildChannel>> {
fire(Request {
body: None,
headers: None,
- route: Route::ChannelsId(guild_id),
- method: Method::Get,
- url: api!("/guilds/{}/channels", guild_id),
+ route: RouteInfo::GetChannels { guild_id },
})
}
@@ -1186,9 +1126,7 @@ pub fn get_current_application_info() -> Result<CurrentApplicationInfo> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::None,
- url: api!("/oauth2/applications/@me").to_owned(),
+ route: RouteInfo::GetCurrentApplicationInfo,
})
}
@@ -1197,9 +1135,7 @@ pub fn get_current_user() -> Result<CurrentUser> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::UsersMe,
- url: api!("/users/@me").to_owned(),
+ route: RouteInfo::GetCurrentUser,
})
}
@@ -1208,9 +1144,7 @@ pub fn get_gateway() -> Result<Gateway> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::Gateway,
- url: api!("/gateway").to_owned(),
+ route: RouteInfo::GetGateway,
})
}
@@ -1219,9 +1153,7 @@ pub fn get_guild(guild_id: u64) -> Result<PartialGuild> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsId(guild_id),
- url: api!("/guilds/{}", guild_id),
+ route: RouteInfo::GetGuild { guild_id },
})
}
@@ -1230,9 +1162,7 @@ pub fn get_guild_embed(guild_id: u64) -> Result<GuildEmbed> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdEmbed(guild_id),
- url: api!("/guilds/{}/embeds", guild_id),
+ route: RouteInfo::GetGuildEmbed { guild_id },
})
}
@@ -1241,9 +1171,7 @@ pub fn get_guild_integrations(guild_id: u64) -> Result<Vec<Integration>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdIntegrations(guild_id),
- url: api!("/guilds/{}/integrations", guild_id),
+ route: RouteInfo::GetGuildIntegrations { guild_id },
})
}
@@ -1252,9 +1180,7 @@ pub fn get_guild_invites(guild_id: u64) -> Result<Vec<RichInvite>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdInvites(guild_id),
- url: api!("/guilds/{}/invites", guild_id),
+ route: RouteInfo::GetGuildInvites { guild_id },
})
}
@@ -1268,9 +1194,7 @@ pub fn get_guild_vanity_url(guild_id: u64) -> Result<String> {
let response = request(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdVanityUrl(guild_id),
- url: api!("/guilds/{}/vanity-url", guild_id),
+ route: RouteInfo::GetGuildVanityUrl { guild_id },
})?;
serde_json::from_reader::<HyperResponse, GuildVanityUrl>(response)
@@ -1287,14 +1211,7 @@ pub fn get_guild_members(guild_id: u64,
let response = request(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdMembers(guild_id),
- url: api!(
- "/guilds/{}/members?limit={}&after={}",
- guild_id,
- limit.unwrap_or(500),
- after.unwrap_or(0),
- ),
+ route: RouteInfo::GetGuildMembers { after, guild_id, limit },
})?;
let mut v = serde_json::from_reader::<HyperResponse, Value>(response)?;
@@ -1314,12 +1231,21 @@ pub fn get_guild_members(guild_id: u64,
/// Gets the amount of users that can be pruned.
pub fn get_guild_prune_count(guild_id: u64, map: &Value) -> Result<GuildPrune> {
+ // Note for 0.6.x: turn this into a function parameter.
+ #[derive(Deserialize)]
+ struct GetGuildPruneCountRequest {
+ days: u64,
+ }
+
+ let req = serde_json::from_value::<GetGuildPruneCountRequest>(map.clone())?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdPrune(guild_id),
- url: api!("/guilds/{}/prune", guild_id),
+ route: RouteInfo::GetGuildPruneCount {
+ days: req.days,
+ guild_id,
+ },
})
}
@@ -1329,9 +1255,7 @@ pub fn get_guild_regions(guild_id: u64) -> Result<Vec<VoiceRegion>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdRegions(guild_id),
- url: api!("/guilds/{}/regions", guild_id),
+ route: RouteInfo::GetGuildRegions { guild_id },
})
}
@@ -1342,9 +1266,7 @@ pub fn get_guild_roles(guild_id: u64) -> Result<Vec<Role>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdRoles(guild_id),
- url: api!("/guilds/{}/roles", guild_id),
+ route: RouteInfo::GetGuildRoles { guild_id },
})
}
@@ -1370,9 +1292,7 @@ pub fn get_guild_webhooks(guild_id: u64) -> Result<Vec<Webhook>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdWebhooks(guild_id),
- url: api!("/guilds/{}/webhooks", guild_id),
+ route: RouteInfo::GetGuildWebhooks { guild_id },
})
}
@@ -1397,48 +1317,30 @@ pub fn get_guild_webhooks(guild_id: u64) -> Result<Vec<Webhook>> {
///
/// [docs]: https://discordapp.com/developers/docs/resources/user#get-current-user-guilds
pub fn get_guilds(target: &GuildPagination, limit: u64) -> Result<Vec<GuildInfo>> {
- let mut uri = format!("/users/@me/guilds?limit={}", limit);
-
- match *target {
- GuildPagination::After(id) => {
- write!(uri, "&after={}", id)?;
- },
- GuildPagination::Before(id) => {
- write!(uri, "&before={}", id)?;
- },
- }
+ let (after, before) = match *target {
+ GuildPagination::After(id) => (Some(id.0), None),
+ GuildPagination::Before(id) => (None, Some(id.0)),
+ };
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::UsersMeGuilds,
- url: api!("{}", uri),
+ route: RouteInfo::GetGuilds { after, before, limit },
})
}
/// Gets information about a specific invite.
#[allow(unused_mut)]
-pub fn get_invite(code: &str, stats: bool) -> Result<Invite> {
- let mut invite = code;
-
+pub fn get_invite(mut code: &str, stats: bool) -> Result<Invite> {
#[cfg(feature = "utils")]
{
- invite = ::utils::parse_invite(invite);
- }
-
- let mut uri = format!("/invites/{}", invite);
-
- if stats {
- uri.push_str("?with_counts=true");
+ code = ::utils::parse_invite(code);
}
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::InvitesCode,
- url: api!("{}", uri),
+ route: RouteInfo::GetInvite { code, stats },
})
}
@@ -1447,9 +1349,7 @@ pub fn get_member(guild_id: u64, user_id: u64) -> Result<Member> {
let response = request(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::GuildsIdMembersId(guild_id),
- url: api!("/guilds/{}/members/{}", guild_id, user_id),
+ route: RouteInfo::GetMember { guild_id, user_id },
})?;
let mut v = serde_json::from_reader::<HyperResponse, Value>(response)?;
@@ -1466,9 +1366,7 @@ pub fn get_message(channel_id: u64, message_id: u64) -> Result<Message> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::ChannelsIdMessagesId(LightMethod::Any, channel_id),
- url: api!("/channels/{}/messages/{}", channel_id, message_id),
+ route: RouteInfo::GetMessage { channel_id, message_id },
})
}
@@ -1477,9 +1375,10 @@ pub fn get_messages(channel_id: u64, query: &str) -> Result<Vec<Message>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::ChannelsIdMessages(channel_id),
- url: api!("/channels/{}/messages{}", channel_id, query),
+ route: RouteInfo::GetMessages {
+ query: query.to_owned(),
+ channel_id,
+ },
})
}
@@ -1488,9 +1387,7 @@ pub fn get_pins(channel_id: u64) -> Result<Vec<Message>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::ChannelsIdPins(channel_id),
- url: api!("/channels/{}/pins", channel_id),
+ route: RouteInfo::GetPins { channel_id },
})
}
@@ -1501,24 +1398,18 @@ pub fn get_reaction_users(channel_id: u64,
limit: u8,
after: Option<u64>)
-> Result<Vec<User>> {
- let mut uri = format!(
- "/channels/{}/messages/{}/reactions/{}?limit={}",
- channel_id,
- message_id,
- reaction_type.as_data(),
- limit
- );
-
- if let Some(user_id) = after {
- write!(uri, "&after={}", user_id)?;
- }
+ let reaction = reaction_type.as_data();
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
- url: api!("{}", uri),
+ route: RouteInfo::GetReactionUsers {
+ after,
+ channel_id,
+ limit,
+ message_id,
+ reaction,
+ },
})
}
@@ -1529,9 +1420,7 @@ pub fn get_unresolved_incidents() -> Result<Vec<Incident>> {
let response = request(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::None,
- url: status!("/incidents/unresolved.json").to_owned(),
+ route: RouteInfo::GetUnresolvedIncidents,
})?;
let mut map: BTreeMap<String, Value> = serde_json::from_reader(response)?;
@@ -1550,9 +1439,7 @@ pub fn get_upcoming_maintenances() -> Result<Vec<Maintenance>> {
let response = request(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::None,
- url: status!("/scheduled-maintenances/upcoming.json").to_owned(),
+ route: RouteInfo::GetUpcomingMaintenances,
})?;
let mut map: BTreeMap<String, Value> = serde_json::from_reader(response)?;
@@ -1569,9 +1456,7 @@ pub fn get_user(user_id: u64) -> Result<User> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::UsersId,
- url: api!("/users/{}", user_id),
+ route: RouteInfo::GetUser { user_id },
})
}
@@ -1580,9 +1465,7 @@ pub fn get_user_dm_channels() -> Result<Vec<PrivateChannel>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::UsersMeChannels,
- url: api!("/users/@me/channels").to_owned(),
+ route: RouteInfo::GetUserDmChannels,
})
}
@@ -1591,9 +1474,7 @@ pub fn get_voice_regions() -> Result<Vec<VoiceRegion>> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::VoiceRegions,
- url: api!("/voice/regions").to_owned(),
+ route: RouteInfo::GetVoiceRegions,
})
}
@@ -1618,9 +1499,7 @@ pub fn get_webhook(webhook_id: u64) -> Result<Webhook> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::WebhooksId(webhook_id),
- url: api!("/webhooks/{}", webhook_id),
+ route: RouteInfo::GetWebhook { webhook_id },
})
}
@@ -1645,9 +1524,7 @@ pub fn get_webhook_with_token(webhook_id: u64, token: &str) -> Result<Webhook> {
fire(Request {
body: None,
headers: None,
- method: Method::Get,
- route: Route::None,
- url: api!("/webhooks/{}/{}", webhook_id, token),
+ route: RouteInfo::GetWebhookWithToken { token, webhook_id },
})
}
@@ -1656,20 +1533,16 @@ pub fn kick_member(guild_id: u64, user_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::GuildsIdMembersId(guild_id),
- url: api!("/guilds/{}/members/{}", guild_id, user_id),
+ route: RouteInfo::KickMember { guild_id, user_id },
})
}
/// Leaves a group DM.
-pub fn leave_group(guild_id: u64) -> Result<Group> {
+pub fn leave_group(group_id: u64) -> Result<Group> {
fire(Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::None,
- url: api!("/channels/{}", guild_id),
+ route: RouteInfo::LeaveGroup { group_id },
})
}
@@ -1678,9 +1551,7 @@ pub fn leave_guild(guild_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::UsersMeGuildsId,
- url: api!("/users/@me/guilds/{}", guild_id),
+ route: RouteInfo::LeaveGuild { guild_id },
})
}
@@ -1689,9 +1560,7 @@ pub fn remove_group_recipient(group_id: u64, user_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::None,
- url: api!("/channels/{}/recipients/{}", group_id, user_id),
+ route: RouteInfo::RemoveGroupRecipient { group_id, user_id },
})
}
@@ -1768,12 +1637,12 @@ pub fn send_files<'a, T, It: IntoIterator<Item=T>>(channel_id: u64, files: It, m
/// Sends a message to a channel.
pub fn send_message(channel_id: u64, map: &Value) -> Result<Message> {
+ let body = serde_json::to_vec(map)?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: Some(&body),
headers: None,
- method: Method::Post,
- route: Route::ChannelsIdMessages(channel_id),
- url: api!("/channels/{}/messages", channel_id),
+ route: RouteInfo::CreateMessage { channel_id },
})
}
@@ -1782,9 +1651,7 @@ pub fn pin_message(channel_id: u64, message_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Put,
- route: Route::ChannelsIdPinsMessageId(channel_id),
- url: api!("/channels/{}/pins/{}", channel_id, message_id),
+ route: RouteInfo::PinMessage { channel_id, message_id },
})
}
@@ -1793,9 +1660,7 @@ pub fn remove_ban(guild_id: u64, user_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::GuildsIdBansUserId(guild_id),
- url: api!("/guilds/{}/bans/{}", guild_id, user_id),
+ route: RouteInfo::RemoveBan { guild_id, user_id },
})
}
@@ -1812,20 +1677,27 @@ pub fn remove_member_role(guild_id: u64, user_id: u64, role_id: u64) -> Result<(
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::GuildsIdMembersIdRolesId(guild_id),
- url: api!("/guilds/{}/members/{}/roles/{}", guild_id, user_id, role_id),
+ route: RouteInfo::RemoveMemberRole { guild_id, user_id, role_id },
})
}
/// Starts removing some members from a guild based on the last time they've been online.
pub fn start_guild_prune(guild_id: u64, map: &Value) -> Result<GuildPrune> {
+ // Note for 0.6.x: turn this into a function parameter.
+ #[derive(Deserialize)]
+ struct StartGuildPruneRequest {
+ days: u64,
+ }
+
+ let req = serde_json::from_value::<StartGuildPruneRequest>(map.clone())?;
+
fire(Request {
- body: Some(map.to_string().into_bytes()),
+ body: None,
headers: None,
- method: Method::Post,
- route: Route::GuildsIdPrune(guild_id),
- url: api!("/guilds/{}/prune", guild_id),
+ route: RouteInfo::StartGuildPrune {
+ days: req.days,
+ guild_id,
+ },
})
}
@@ -1834,9 +1706,7 @@ pub fn start_integration_sync(guild_id: u64, integration_id: u64) -> Result<()>
wind(204, Request {
body: None,
headers: None,
- method: Method::Post,
- route: Route::GuildsIdIntegrationsIdSync(guild_id),
- url: api!("/guilds/{}/integrations/{}/sync", guild_id, integration_id),
+ route: RouteInfo::StartIntegrationSync { guild_id, integration_id },
})
}
@@ -1845,9 +1715,7 @@ pub fn unpin_message(channel_id: u64, message_id: u64) -> Result<()> {
wind(204, Request {
body: None,
headers: None,
- method: Method::Delete,
- route: Route::ChannelsIdPinsMessageId(channel_id),
- url: api!("/channels/{}/pins/{}", channel_id, message_id),
+ route: RouteInfo::UnpinMessage { channel_id, message_id },
})
}
@@ -1873,33 +1741,19 @@ fn request(req: Request) -> Result<HyperResponse> {
}
}
-fn build_req(req: &Request) -> RequestBuilder {
- let mut builder = CLIENT.request(req.method.clone(), &req.url);
-
- if let Some(ref bytes) = req.body {
- builder = builder.body(HyperBody::BufBody(bytes, bytes.len()));
- }
-
- if let Some(headers) = req.headers.clone() {
- builder = builder.headers(headers);
- }
-
- builder
-}
-
-fn retry(req: &Request) -> HyperResult<HyperResponse> {
+fn retry(request: &Request) -> HyperResult<HyperResponse> {
// Retry the request twice in a loop until it succeeds.
//
// If it doesn't and the loop breaks, try one last time.
for _ in 0..=2 {
- match build_req(req).send() {
+ match request.build().send() {
Err(HyperError::Io(ref io))
if io.kind() == IoErrorKind::ConnectionAborted => continue,
other => return other,
}
}
- build_req(req).send()
+ request.build().send()
}
/// Performs a request and then verifies that the response status code is equal
@@ -1908,16 +1762,16 @@ fn retry(req: &Request) -> HyperResult<HyperResponse> {
/// This is a function that performs a light amount of work and returns an
/// empty tuple, so it's called "wind" to denote that it's lightweight.
fn wind(expected: u16, req: Request) -> Result<()> {
- let response = request(req)?;
+ let resp = request(req)?;
- if response.status.to_u16() == expected {
+ if resp.status.to_u16() == expected {
return Ok(());
}
- debug!("Expected {}, got {}", expected, response.status);
- trace!("Unsuccessful response: {:?}", response);
+ debug!("Expected {}, got {}", expected, resp.status);
+ trace!("Unsuccessful response: {:?}", resp);
- Err(Error::Http(HttpError::UnsuccessfulRequest(response)))
+ Err(Error::Http(HttpError::UnsuccessfulRequest(resp)))
}
/// Enum that allows a user to pass a `Path` or a `File` type to `send_files`
diff --git a/src/http/ratelimiting.rs b/src/http/ratelimiting.rs
index 1c31c9f..309ba35 100644
--- a/src/http/ratelimiting.rs
+++ b/src/http/ratelimiting.rs
@@ -40,6 +40,8 @@
//! [Taken from]: https://discordapp.com/developers/docs/topics/rate-limits#rate-limits
#![allow(zero_ptr)]
+pub use super::routing::Route;
+
use chrono::{DateTime, Utc};
use hyper::client::Response;
use hyper::header::Headers;
@@ -54,7 +56,7 @@ use std::{
thread,
i64
};
-use super::{HttpError, LightMethod, Request};
+use super::{HttpError, Request};
/// Refer to [`offset`].
///
@@ -102,271 +104,22 @@ 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 [`http`] module.
-///
-/// [`http`]: ../index.html
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum Route {
- /// Route for the `/channels/:channel_id` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsId(u64),
- /// Route for the `/channels/:channel_id/invites` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdInvites(u64),
- /// Route for the `/channels/:channel_id/messages` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdMessages(u64),
- /// Route for the `/channels/:channel_id/messages/bulk-delete` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdMessagesBulkDelete(u64),
- /// Route for the `/channels/:channel_id/messages/:message_id` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- // This route is a unique case. The ratelimit for message _deletions_ is
- // different than the overall route ratelimit.
- //
- // Refer to the docs on [Rate Limits] in the yellow warning section.
- //
- // Additionally, this needs to be a `LightMethod` from the parent module
- // and _not_ a `hyper` `Method` due to `hyper`'s not deriving `Copy`.
- //
- // [Rate Limits]: https://discordapp.com/developers/docs/topics/rate-limits
- ChannelsIdMessagesId(LightMethod, u64),
- /// Route for the `/channels/:channel_id/messages/:message_id/ack` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdMessagesIdAck(u64),
- /// Route for the `/channels/:channel_id/messages/:message_id/reactions`
- /// path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdMessagesIdReactions(u64),
- /// Route for the
- /// `/channels/:channel_id/messages/:message_id/reactions/:reaction/@me`
- /// path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdMessagesIdReactionsUserIdType(u64),
- /// Route for the `/channels/:channel_id/permissions/:target_id` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdPermissionsOverwriteId(u64),
- /// Route for the `/channels/:channel_id/pins` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdPins(u64),
- /// Route for the `/channels/:channel_id/pins/:message_id` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdPinsMessageId(u64),
- /// Route for the `/channels/:channel_id/typing` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdTyping(u64),
- /// Route for the `/channels/:channel_id/webhooks` path.
- ///
- /// The data is the relevant [`ChannelId`].
- ///
- /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
- ChannelsIdWebhooks(u64),
- /// Route for the `/gateway` path.
- Gateway,
- /// Route for the `/gateway/bot` path.
- GatewayBot,
- /// Route for the `/guilds` path.
- Guilds,
- /// Route for the `/guilds/:guild_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsId(u64),
- /// Route for the `/guilds/:guild_id/bans` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdBans(u64),
- /// Route for the `/guilds/:guild_id/audit-logs` path.
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdAuditLogs(u64),
- /// Route for the `/guilds/:guild_id/bans/:user_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdBansUserId(u64),
- /// Route for the `/guilds/:guild_id/channels/:channel_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdChannels(u64),
- /// Route for the `/guilds/:guild_id/embed` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdEmbed(u64),
- /// Route for the `/guilds/:guild_id/emojis` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdEmojis(u64),
- /// Route for the `/guilds/:guild_id/emojis/:emoji_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdEmojisId(u64),
- /// Route for the `/guilds/:guild_id/integrations` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdIntegrations(u64),
- /// Route for the `/guilds/:guild_id/integrations/:integration_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdIntegrationsId(u64),
- /// Route for the `/guilds/:guild_id/integrations/:integration_id/sync`
- /// path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdIntegrationsIdSync(u64),
- /// Route for the `/guilds/:guild_id/invites` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdInvites(u64),
- /// Route for the `/guilds/:guild_id/members` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdMembers(u64),
- /// Route for the `/guilds/:guild_id/members/:user_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdMembersId(u64),
- /// Route for the `/guilds/:guild_id/members/:user_id/roles/:role_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdMembersIdRolesId(u64),
- /// Route for the `/guilds/:guild_id/members/@me/nick` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdMembersMeNick(u64),
- /// Route for the `/guilds/:guild_id/prune` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdPrune(u64),
- /// Route for the `/guilds/:guild_id/regions` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdRegions(u64),
- /// Route for the `/guilds/:guild_id/roles` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdRoles(u64),
- /// Route for the `/guilds/:guild_id/roles/:role_id` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdRolesId(u64),
- /// Route for the `/guilds/:guild_id/vanity-url` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdVanityUrl(u64),
- /// Route for the `/guilds/:guild_id/webhooks` path.
- ///
- /// The data is the relevant [`GuildId`].
- ///
- /// [`GuildId`]: struct.GuildId.html
- GuildsIdWebhooks(u64),
- /// Route for the `/invites/:code` path.
- InvitesCode,
- /// Route for the `/users/:user_id` path.
- UsersId,
- /// Route for the `/users/@me` path.
- UsersMe,
- /// Route for the `/users/@me/channels` path.
- UsersMeChannels,
- /// Route for the `/users/@me/guilds` path.
- UsersMeGuilds,
- /// Route for the `/users/@me/guilds/:guild_id` path.
- UsersMeGuildsId,
- /// Route for the `/voice/regions` path.
- VoiceRegions,
- /// Route for the `/webhooks/:webhook_id` path.
- WebhooksId(u64),
- /// Route where no ratelimit headers are in place (i.e. user account-only
- /// routes).
- ///
- /// This is a special case, in that if the route is `None` then pre- and
- /// post-hooks are not executed.
- None,
-}
-
pub(super) fn perform(req: Request) -> Result<Response> {
loop {
// This will block if another thread already has the global
// unlocked already (due to receiving an x-ratelimit-global).
let _ = GLOBAL.lock();
+ // Destructure the tuple instead of retrieving the third value to
+ // take advantage of the type system. If `RouteInfo::deconstruct`
+ // returns a different number of tuple elements in the future, directly
+ // accessing a certain index (e.g. `req.route.deconstruct().1`) would
+ // mean this code would not indicate it might need to be updated for the
+ // new tuple element amount.
+ //
+ // This isn't normally important, but might be for ratelimiting.
+ let (_, route, _) = req.route.deconstruct();
+
// Perform pre-checking here:
//
// - get the route's relevant rate
@@ -377,7 +130,7 @@ pub(super) fn perform(req: Request) -> Result<Response> {
// - then, perform the request
let bucket = Arc::clone(ROUTES
.lock()
- .entry(req.route)
+ .entry(route)
.or_insert_with(|| {
Arc::new(Mutex::new(RateLimit {
limit: i64::MAX,
@@ -387,7 +140,7 @@ pub(super) fn perform(req: Request) -> Result<Response> {
}));
let mut lock = bucket.lock();
- lock.pre_hook(&req.route);
+ lock.pre_hook(&route);
let response = super::retry(&req)?;
@@ -415,7 +168,7 @@ pub(super) fn perform(req: Request) -> Result<Response> {
// It _may_ be possible for the limit to be raised at any time,
// so check if it did from the value of the 'x-ratelimit-limit'
// header. If the limit was 5 and is now 7, add 2 to the 'remaining'
- if req.route == Route::None {
+ if route == Route::None {
return Ok(response);
} else {
let redo = if response.headers.get_raw("x-ratelimit-global").is_some() {
@@ -423,7 +176,7 @@ pub(super) fn perform(req: Request) -> Result<Response> {
Ok(
if let Some(retry_after) = parse_header(&response.headers, "retry-after")? {
- debug!("Ratelimited on route {:?} for {:?}ms", req.route, retry_after);
+ debug!("Ratelimited on route {:?} for {:?}ms", route, retry_after);
thread::sleep(Duration::from_millis(retry_after as u64));
true
@@ -432,7 +185,7 @@ pub(super) fn perform(req: Request) -> Result<Response> {
},
)
} else {
- lock.post_hook(&response, &req.route)
+ lock.post_hook(&response, &route)
};
if !redo.unwrap_or(true) {
diff --git a/src/http/routing.rs b/src/http/routing.rs
new file mode 100644
index 0000000..dfbbb7f
--- /dev/null
+++ b/src/http/routing.rs
@@ -0,0 +1,1433 @@
+use std::{
+ borrow::Cow,
+ fmt::{Display, Write},
+};
+use super::LightMethod;
+
+/// 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 [`http`] module.
+///
+/// [`http`]: ../index.html
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub enum Route {
+ /// Route for the `/channels/:channel_id` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsId(u64),
+ /// Route for the `/channels/:channel_id/invites` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdInvites(u64),
+ /// Route for the `/channels/:channel_id/messages` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdMessages(u64),
+ /// Route for the `/channels/:channel_id/messages/bulk-delete` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdMessagesBulkDelete(u64),
+ /// Route for the `/channels/:channel_id/messages/:message_id` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ // This route is a unique case. The ratelimit for message _deletions_ is
+ // different than the overall route ratelimit.
+ //
+ // Refer to the docs on [Rate Limits] in the yellow warning section.
+ //
+ // Additionally, this needs to be a `LightMethod` from the parent module
+ // and _not_ a `hyper` `Method` due to `hyper`'s not deriving `Copy`.
+ //
+ // [Rate Limits]: https://discordapp.com/developers/docs/topics/rate-limits
+ ChannelsIdMessagesId(LightMethod, u64),
+ /// Route for the `/channels/:channel_id/messages/:message_id/ack` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdMessagesIdAck(u64),
+ /// Route for the `/channels/:channel_id/messages/:message_id/reactions`
+ /// path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdMessagesIdReactions(u64),
+ /// Route for the
+ /// `/channels/:channel_id/messages/:message_id/reactions/:reaction/@me`
+ /// path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdMessagesIdReactionsUserIdType(u64),
+ /// Route for the `/channels/:channel_id/permissions/:target_id` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdPermissionsOverwriteId(u64),
+ /// Route for the `/channels/:channel_id/pins` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdPins(u64),
+ /// Route for the `/channels/:channel_id/pins/:message_id` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdPinsMessageId(u64),
+ /// Route for the `/channels/:channel_id/typing` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdTyping(u64),
+ /// Route for the `/channels/:channel_id/webhooks` path.
+ ///
+ /// The data is the relevant [`ChannelId`].
+ ///
+ /// [`ChannelId`]: ../../model/id/struct.ChannelId.html
+ ChannelsIdWebhooks(u64),
+ /// Route for the `/gateway` path.
+ Gateway,
+ /// Route for the `/gateway/bot` path.
+ GatewayBot,
+ /// Route for the `/guilds` path.
+ Guilds,
+ /// Route for the `/guilds/:guild_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsId(u64),
+ /// Route for the `/guilds/:guild_id/bans` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdBans(u64),
+ /// Route for the `/guilds/:guild_id/audit-logs` path.
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdAuditLogs(u64),
+ /// Route for the `/guilds/:guild_id/bans/:user_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdBansUserId(u64),
+ /// Route for the `/guilds/:guild_id/channels/:channel_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdChannels(u64),
+ /// Route for the `/guilds/:guild_id/embed` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdEmbed(u64),
+ /// Route for the `/guilds/:guild_id/emojis` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdEmojis(u64),
+ /// Route for the `/guilds/:guild_id/emojis/:emoji_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdEmojisId(u64),
+ /// Route for the `/guilds/:guild_id/integrations` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdIntegrations(u64),
+ /// Route for the `/guilds/:guild_id/integrations/:integration_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdIntegrationsId(u64),
+ /// Route for the `/guilds/:guild_id/integrations/:integration_id/sync`
+ /// path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdIntegrationsIdSync(u64),
+ /// Route for the `/guilds/:guild_id/invites` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdInvites(u64),
+ /// Route for the `/guilds/:guild_id/members` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdMembers(u64),
+ /// Route for the `/guilds/:guild_id/members/:user_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdMembersId(u64),
+ /// Route for the `/guilds/:guild_id/members/:user_id/roles/:role_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdMembersIdRolesId(u64),
+ /// Route for the `/guilds/:guild_id/members/@me/nick` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdMembersMeNick(u64),
+ /// Route for the `/guilds/:guild_id/prune` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdPrune(u64),
+ /// Route for the `/guilds/:guild_id/regions` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdRegions(u64),
+ /// Route for the `/guilds/:guild_id/roles` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdRoles(u64),
+ /// Route for the `/guilds/:guild_id/roles/:role_id` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdRolesId(u64),
+ /// Route for the `/guilds/:guild_id/vanity-url` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdVanityUrl(u64),
+ /// Route for the `/guilds/:guild_id/webhooks` path.
+ ///
+ /// The data is the relevant [`GuildId`].
+ ///
+ /// [`GuildId`]: struct.GuildId.html
+ GuildsIdWebhooks(u64),
+ /// Route for the `/invites/:code` path.
+ InvitesCode,
+ /// Route for the `/users/:user_id` path.
+ UsersId,
+ /// Route for the `/users/@me` path.
+ UsersMe,
+ /// Route for the `/users/@me/channels` path.
+ UsersMeChannels,
+ /// Route for the `/users/@me/guilds` path.
+ UsersMeGuilds,
+ /// Route for the `/users/@me/guilds/:guild_id` path.
+ UsersMeGuildsId,
+ /// Route for the `/voice/regions` path.
+ VoiceRegions,
+ /// Route for the `/webhooks/:webhook_id` path.
+ WebhooksId(u64),
+ /// Route where no ratelimit headers are in place (i.e. user account-only
+ /// routes).
+ ///
+ /// This is a special case, in that if the route is `None` then pre- and
+ /// post-hooks are not executed.
+ None,
+}
+
+impl Route {
+ pub fn channel(channel_id: u64) -> String {
+ format!(api!("/channels/{}"), channel_id)
+ }
+
+ pub fn channel_invites(channel_id: u64) -> String {
+ format!(api!("/channels/{}/invites"), channel_id)
+ }
+
+ pub fn channel_message(channel_id: u64, message_id: u64) -> String {
+ format!(api!("/channels/{}/messages/{}"), channel_id, message_id)
+ }
+
+ pub fn channel_message_reaction<D, T>(
+ channel_id: u64,
+ message_id: u64,
+ user_id: D,
+ reaction_type: T
+ ) -> String where D: Display, T: Display {
+ format!(
+ api!("/channels/{}/messages/{}/reactions/{}/{}"),
+ channel_id,
+ message_id,
+ reaction_type,
+ user_id,
+ )
+ }
+
+ pub fn channel_message_reactions(
+ channel_id: u64,
+ message_id: u64,
+ ) -> String {
+ api!("/channels/{}/messages/{}/reactions", channel_id, message_id)
+ }
+
+ pub fn channel_message_reactions_list(
+ channel_id: u64,
+ message_id: u64,
+ reaction: &str,
+ limit: u8,
+ after: Option<u64>,
+ ) -> String {
+ let mut uri = format!(
+ api!("/channels/{}/messages/{}/reactions/{}?limit={}"),
+ channel_id,
+ message_id,
+ reaction,
+ limit,
+ );
+
+ if let Some(after) = after {
+ let _ = write!(uri, "&after={}", after);
+ }
+
+ uri
+ }
+
+ pub fn channel_messages(channel_id: u64, query: Option<&str>) -> String {
+ format!(
+ api!("/channels/{}/messages{}"),
+ channel_id,
+ query.unwrap_or(""),
+ )
+ }
+
+ pub fn channel_messages_bulk_delete(channel_id: u64) -> String {
+ format!(api!("/channels/{}/messages/bulk-delete"), channel_id)
+ }
+
+ pub fn channel_permission(channel_id: u64, target_id: u64) -> String {
+ format!(api!("/channels/{}/permissions/{}"), channel_id, target_id)
+ }
+
+ pub fn channel_pin(channel_id: u64, message_id: u64) -> String {
+ format!(api!("/channels/{}/pins/{}"), channel_id, message_id)
+ }
+
+ pub fn channel_pins(channel_id: u64) -> String {
+ format!(api!("/channels/{}/pins"), channel_id)
+ }
+
+ pub fn channel_typing(channel_id: u64) -> String {
+ format!(api!("/channels/{}/typing"), channel_id)
+ }
+
+ pub fn channel_webhooks(channel_id: u64) -> String {
+ format!(api!("/channels/{}/webhooks"), channel_id)
+ }
+
+ pub fn gateway() -> &'static str {
+ api!("/gateway")
+ }
+
+ pub fn gateway_bot() -> &'static str {
+ api!("/gateway/bot")
+ }
+
+ pub fn group_recipient(group_id: u64, user_id: u64) -> String {
+ format!(api!("/channels/{}/recipients/{}"), group_id, user_id)
+ }
+
+ pub fn guild(guild_id: u64) -> String {
+ format!(api!("/guilds/{}"), guild_id)
+ }
+
+ pub fn guild_audit_logs(
+ guild_id: u64,
+ action_type: Option<u8>,
+ user_id: Option<u64>,
+ before: Option<u64>,
+ limit: Option<u8>,
+ ) -> String {
+ let mut s = format!(
+ api!("/guilds/{}/audit-logs?"),
+ guild_id,
+ );
+
+ if let Some(action_type) = action_type {
+ let _ = write!(s, "&action_type={}", action_type);
+ }
+
+ if let Some(before) = before {
+ let _ = write!(s, "&before={}", before);
+ }
+
+ if let Some(limit) = limit {
+ let _ = write!(s, "&limit={}", limit);
+ }
+
+ if let Some(user_id) = user_id {
+ let _ = write!(s, "&user_id={}", user_id);
+ }
+
+ s
+ }
+
+ pub fn guild_ban(guild_id: u64, user_id: u64) -> String {
+ format!(api!("/guilds/{}/bans/{}"), guild_id, user_id)
+ }
+
+ pub fn guild_ban_optioned(
+ guild_id: u64,
+ user_id: u64,
+ delete_message_days: u8,
+ reason: &str,
+ ) -> String {
+ format!(
+ api!("/guilds/{}/bans/{}?delete_message_days={}&reason={}"),
+ guild_id,
+ user_id,
+ delete_message_days,
+ reason,
+ )
+ }
+
+ pub fn guild_bans(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/bans"), guild_id)
+ }
+
+ pub fn guild_channels(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/channels"), guild_id)
+ }
+
+ pub fn guild_embed(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/embed"), guild_id)
+ }
+
+ pub fn guild_emojis(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/emojis"), guild_id)
+ }
+
+ pub fn guild_emoji(guild_id: u64, emoji_id: u64) -> String {
+ format!(api!("/guilds/{}/emojis/{}"), guild_id, emoji_id)
+ }
+
+ pub fn guild_integration(
+ guild_id: u64,
+ integration_id: u64,
+ ) -> String {
+ format!(api!("/guilds/{}/integrations/{}"), guild_id, integration_id)
+ }
+
+ pub fn guild_integration_sync(
+ guild_id: u64,
+ integration_id: u64,
+ ) -> String {
+ format!(
+ api!("/guilds/{}/integrations/{}/sync"),
+ guild_id,
+ integration_id,
+ )
+ }
+
+ pub fn guild_integrations(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/integrations"), guild_id)
+ }
+
+ pub fn guild_invites(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/invites"), guild_id)
+ }
+
+ pub fn guild_member(guild_id: u64, user_id: u64) -> String {
+ format!(api!("/guilds/{}/members/{}"), guild_id, user_id)
+ }
+
+ pub fn guild_member_role(
+ guild_id: u64,
+ user_id: u64,
+ role_id: u64,
+ ) -> String {
+ format!(
+ api!("/guilds/{}/members/{}/roles/{}"),
+ guild_id,
+ user_id,
+ role_id,
+ )
+ }
+
+ pub fn guild_members(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/members"), guild_id)
+ }
+
+ pub fn guild_members_optioned(
+ guild_id: u64,
+ after: Option<u64>,
+ limit: Option<u64>,
+ ) -> String {
+ let mut s = format!(api!("/guilds/{}/members?"), guild_id);
+
+ if let Some(after) = after {
+ let _ = write!(s, "&after={}", after);
+ }
+
+ if let Some(limit) = limit {
+ let _ = write!(s, "&limit={}", limit);
+ }
+
+ s
+ }
+
+ pub fn guild_nickname(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/members/@me/nick"), guild_id)
+ }
+
+ pub fn guild_prune(guild_id: u64, days: u64) -> String {
+ format!(api!("/guilds/{}/prune?days={}"), guild_id, days)
+ }
+
+ pub fn guild_regions(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/regions"), guild_id)
+ }
+
+ pub fn guild_role(guild_id: u64, role_id: u64) -> String {
+ format!(api!("/guilds/{}/roles/{}"), guild_id, role_id)
+ }
+
+ pub fn guild_roles(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/roles"), guild_id)
+ }
+
+ pub fn guild_vanity_url(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/vanity-url"), guild_id)
+ }
+
+ pub fn guild_webhooks(guild_id: u64) -> String {
+ format!(api!("/guilds/{}/webhooks"), guild_id)
+ }
+
+ pub fn guilds() -> &'static str {
+ api!("/guilds")
+ }
+
+ pub fn invite(code: &str) -> String {
+ format!(api!("/invites/{}"), code)
+ }
+
+ pub fn invite_optioned(code: &str, stats: bool) -> String {
+ format!(api!("/invites/{}?with_counts={}"), code, stats)
+ }
+
+ pub fn oauth2_application_current() -> &'static str {
+ api!("/oauth2/applications/@me")
+ }
+
+ pub fn private_channel() -> &'static str {
+ api!("/users/@me/channels")
+ }
+
+ pub fn status_incidents_unresolved() -> &'static str {
+ status!("/incidents/unresolved.json")
+ }
+
+ pub fn status_maintenances_active() -> &'static str {
+ status!("/scheduled-maintenances/active.json")
+ }
+
+ pub fn status_maintenances_upcoming() -> &'static str {
+ status!("/scheduled-maintenances/upcoming.json")
+ }
+
+ pub fn user<D: Display>(target: D) -> String {
+ format!(api!("/users/{}"), target)
+ }
+
+ pub fn user_dm_channels<D: Display>(target: D) -> String {
+ format!(api!("/users/{}/channels"), target)
+ }
+
+ pub fn user_guild<D: Display>(target: D, guild_id: u64) -> String {
+ format!(api!("/users/{}/guilds/{}"), target, guild_id)
+ }
+
+ pub fn user_guilds<D: Display>(target: D) -> String {
+ format!(api!("/users/{}/guilds"), target)
+ }
+
+ pub fn user_guilds_optioned<D: Display>(
+ target: D,
+ after: Option<u64>,
+ before: Option<u64>,
+ limit: u64,
+ ) -> String {
+ let mut s = format!(api!("/users/{}/guilds?limit={}&"), target, limit);
+
+ if let Some(after) = after {
+ let _ = write!(s, "&after={}", after);
+ }
+
+ if let Some(before) = before {
+ let _ = write!(s, "&before={}", before);
+ }
+
+ s
+ }
+
+ pub fn voice_regions() -> &'static str {
+ api!("/voice/regions")
+ }
+
+ pub fn webhook(webhook_id: u64) -> String {
+ format!(api!("/webhooks/{}"), webhook_id)
+ }
+
+ pub fn webhook_with_token<D>(webhook_id: u64, token: D) -> String
+ where D: Display {
+ format!(api!("/webhooks/{}/{}"), webhook_id, token)
+ }
+
+ pub fn webhook_with_token_optioned<D>(webhook_id: u64, token: D, wait: bool)
+ -> String where D: Display {
+ format!(api!("/webhooks/{}/{}?wait={}"), webhook_id, token, wait)
+ }
+}
+
+#[derive(Clone, Debug)]
+pub enum RouteInfo<'a> {
+ AddGroupRecipient {
+ group_id: u64,
+ user_id: u64,
+ },
+ AddMemberRole {
+ guild_id: u64,
+ role_id: u64,
+ user_id: u64,
+ },
+ GuildBanUser {
+ guild_id: u64,
+ user_id: u64,
+ delete_message_days: Option<u8>,
+ reason: Option<&'a str>,
+ },
+ BroadcastTyping {
+ channel_id: u64,
+ },
+ CreateChannel {
+ guild_id: u64,
+ },
+ CreateEmoji {
+ guild_id: u64,
+ },
+ CreateGuild,
+ CreateGuildIntegration {
+ guild_id: u64,
+ integration_id: u64,
+ },
+ CreateInvite {
+ channel_id: u64,
+ },
+ CreateMessage {
+ channel_id: u64,
+ },
+ CreatePermission {
+ channel_id: u64,
+ target_id: u64,
+ },
+ CreatePrivateChannel,
+ CreateReaction {
+ channel_id: u64,
+ message_id: u64,
+ reaction: &'a str,
+ },
+ CreateRole {
+ guild_id: u64,
+ },
+ CreateWebhook {
+ channel_id: u64,
+ },
+ DeleteChannel {
+ channel_id: u64,
+ },
+ DeleteEmoji {
+ guild_id: u64,
+ emoji_id: u64,
+ },
+ DeleteGuild {
+ guild_id: u64,
+ },
+ DeleteGuildIntegration {
+ guild_id: u64,
+ integration_id: u64,
+ },
+ DeleteInvite {
+ code: &'a str,
+ },
+ DeleteMessage {
+ channel_id: u64,
+ message_id: u64,
+ },
+ DeleteMessages {
+ channel_id: u64,
+ },
+ DeleteMessageReactions {
+ channel_id: u64,
+ message_id: u64,
+ },
+ DeletePermission {
+ channel_id: u64,
+ target_id: u64,
+ },
+ DeleteReaction {
+ channel_id: u64,
+ message_id: u64,
+ user: &'a str,
+ reaction: &'a str,
+ },
+ DeleteRole {
+ guild_id: u64,
+ role_id: u64,
+ },
+ DeleteWebhook {
+ webhook_id: u64,
+ },
+ DeleteWebhookWithToken {
+ token: &'a str,
+ webhook_id: u64,
+ },
+ EditChannel {
+ channel_id: u64,
+ },
+ EditEmoji {
+ guild_id: u64,
+ emoji_id: u64,
+ },
+ EditGuild {
+ guild_id: u64,
+ },
+ EditGuildChannels {
+ guild_id: u64,
+ },
+ EditGuildEmbed {
+ guild_id: u64,
+ },
+ EditMember {
+ guild_id: u64,
+ user_id: u64,
+ },
+ EditMessage {
+ channel_id: u64,
+ message_id: u64,
+ },
+ EditNickname {
+ guild_id: u64,
+ },
+ EditProfile,
+ EditRole {
+ guild_id: u64,
+ role_id: u64,
+ },
+ EditWebhook {
+ webhook_id: u64,
+ },
+ EditWebhookWithToken {
+ token: &'a str,
+ webhook_id: u64,
+ },
+ ExecuteWebhook {
+ token: &'a str,
+ wait: bool,
+ webhook_id: u64,
+ },
+ GetActiveMaintenance,
+ GetAuditLogs {
+ action_type: Option<u8>,
+ before: Option<u64>,
+ guild_id: u64,
+ limit: Option<u8>,
+ user_id: Option<u64>,
+ },
+ GetBans {
+ guild_id: u64,
+ },
+ GetBotGateway,
+ GetChannel {
+ channel_id: u64,
+ },
+ GetChannelInvites {
+ channel_id: u64,
+ },
+ GetChannelWebhooks {
+ channel_id: u64,
+ },
+ GetChannels {
+ guild_id: u64,
+ },
+ GetCurrentApplicationInfo,
+ GetCurrentUser,
+ GetGateway,
+ GetGuild {
+ guild_id: u64,
+ },
+ GetGuildEmbed {
+ guild_id: u64,
+ },
+ GetGuildIntegrations {
+ guild_id: u64,
+ },
+ GetGuildInvites {
+ guild_id: u64,
+ },
+ GetGuildMembers {
+ after: Option<u64>,
+ limit: Option<u64>,
+ guild_id: u64,
+ },
+ GetGuildPruneCount {
+ days: u64,
+ guild_id: u64,
+ },
+ GetGuildRegions {
+ guild_id: u64,
+ },
+ GetGuildRoles {
+ guild_id: u64,
+ },
+ GetGuildVanityUrl {
+ guild_id: u64,
+ },
+ GetGuildWebhooks {
+ guild_id: u64,
+ },
+ GetGuilds {
+ after: Option<u64>,
+ before: Option<u64>,
+ limit: u64,
+ },
+ GetInvite {
+ code: &'a str,
+ stats: bool,
+ },
+ GetMember {
+ guild_id: u64,
+ user_id: u64,
+ },
+ GetMessage {
+ channel_id: u64,
+ message_id: u64,
+ },
+ GetMessages {
+ channel_id: u64,
+ query: String,
+ },
+ GetPins {
+ channel_id: u64,
+ },
+ GetReactionUsers {
+ after: Option<u64>,
+ channel_id: u64,
+ limit: u8,
+ message_id: u64,
+ reaction: String,
+ },
+ GetUnresolvedIncidents,
+ GetUpcomingMaintenances,
+ GetUser {
+ user_id: u64,
+ },
+ GetUserDmChannels,
+ GetVoiceRegions,
+ GetWebhook {
+ webhook_id: u64,
+ },
+ GetWebhookWithToken {
+ token: &'a str,
+ webhook_id: u64,
+ },
+ KickMember {
+ guild_id: u64,
+ user_id: u64,
+ },
+ LeaveGroup {
+ group_id: u64,
+ },
+ LeaveGuild {
+ guild_id: u64,
+ },
+ RemoveGroupRecipient {
+ group_id: u64,
+ user_id: u64,
+ },
+ PinMessage {
+ channel_id: u64,
+ message_id: u64,
+ },
+ RemoveBan {
+ guild_id: u64,
+ user_id: u64,
+ },
+ RemoveMemberRole {
+ guild_id: u64,
+ role_id: u64,
+ user_id: u64,
+ },
+ StartGuildPrune {
+ days: u64,
+ guild_id: u64,
+ },
+ StartIntegrationSync {
+ guild_id: u64,
+ integration_id: u64,
+ },
+ StatusIncidentsUnresolved,
+ StatusMaintenancesActive,
+ StatusMaintenancesUpcoming,
+ UnpinMessage {
+ channel_id: u64,
+ message_id: u64,
+ },
+}
+
+impl<'a> RouteInfo<'a> {
+ pub fn deconstruct(&self) -> (LightMethod, Route, Cow<str>) {
+ match *self {
+ RouteInfo::AddGroupRecipient { group_id, user_id } => (
+ LightMethod::Post,
+ Route::None,
+ Cow::from(Route::group_recipient(group_id, user_id)),
+ ),
+ RouteInfo::AddMemberRole { guild_id, role_id, user_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdMembersIdRolesId(guild_id),
+ Cow::from(Route::guild_member_role(guild_id, user_id, role_id)),
+ ),
+ RouteInfo::GuildBanUser {
+ guild_id,
+ delete_message_days,
+ reason,
+ user_id,
+ } => (
+ // TODO
+ LightMethod::Delete,
+ Route::GuildsIdBansUserId(guild_id),
+ Cow::from(Route::guild_ban_optioned(
+ guild_id,
+ user_id,
+ delete_message_days.unwrap_or(0),
+ reason.unwrap_or(""),
+ )),
+ ),
+ RouteInfo::BroadcastTyping { channel_id } => (
+ LightMethod::Post,
+ Route::ChannelsIdTyping(channel_id),
+ Cow::from(Route::channel_typing(channel_id)),
+ ),
+ RouteInfo::CreateChannel { guild_id } => (
+ LightMethod::Post,
+ Route::GuildsIdChannels(guild_id),
+ Cow::from(Route::guild_channels(guild_id)),
+ ),
+ RouteInfo::CreateEmoji { guild_id } => (
+ LightMethod::Post,
+ Route::GuildsIdEmojis(guild_id),
+ Cow::from(Route::guild_emojis(guild_id)),
+ ),
+ RouteInfo::CreateGuild => (
+ LightMethod::Post,
+ Route::Guilds,
+ Cow::from(Route::guilds()),
+ ),
+ RouteInfo::CreateGuildIntegration { guild_id, integration_id } => (
+ LightMethod::Post,
+ Route::GuildsIdIntegrationsId(guild_id),
+ Cow::from(Route::guild_integration(guild_id, integration_id)),
+ ),
+ RouteInfo::CreateInvite { channel_id } => (
+ LightMethod::Post,
+ Route::ChannelsIdInvites(channel_id),
+ Cow::from(Route::channel_invites(channel_id)),
+ ),
+ RouteInfo::CreateMessage { channel_id } => (
+ LightMethod::Post,
+ Route::ChannelsIdMessages(channel_id),
+ Cow::from(Route::channel_messages(channel_id, None)),
+ ),
+ RouteInfo::CreatePermission { channel_id, target_id } => (
+ LightMethod::Post,
+ Route::ChannelsIdPermissionsOverwriteId(channel_id),
+ Cow::from(Route::channel_permission(channel_id, target_id)),
+ ),
+ RouteInfo::CreatePrivateChannel => (
+ LightMethod::Post,
+ Route::UsersMeChannels,
+ Cow::from(Route::user_dm_channels("@me")),
+ ),
+ RouteInfo::CreateReaction { channel_id, message_id, reaction } => (
+ LightMethod::Put,
+ Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
+ Cow::from(Route::channel_message_reaction(
+ channel_id,
+ message_id,
+ "@me",
+ reaction,
+ )),
+ ),
+ RouteInfo::CreateRole { guild_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdRoles(guild_id),
+ Cow::from(Route::guild_roles(guild_id)),
+ ),
+ RouteInfo::CreateWebhook { channel_id } => (
+ LightMethod::Delete,
+ Route::ChannelsIdWebhooks(channel_id),
+ Cow::from(Route::channel_webhooks(channel_id)),
+ ),
+ RouteInfo::DeleteChannel { channel_id } => (
+ LightMethod::Delete,
+ Route::ChannelsId(channel_id),
+ Cow::from(Route::channel(channel_id)),
+ ),
+ RouteInfo::DeleteEmoji { emoji_id, guild_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdEmojisId(guild_id),
+ Cow::from(Route::guild_emoji(guild_id, emoji_id)),
+ ),
+ RouteInfo::DeleteGuild { guild_id } => (
+ LightMethod::Delete,
+ Route::GuildsId(guild_id),
+ Cow::from(Route::guild(guild_id)),
+ ),
+ RouteInfo::DeleteGuildIntegration { guild_id, integration_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdIntegrationsId(guild_id),
+ Cow::from(Route::guild_integration(guild_id, integration_id)),
+ ),
+ RouteInfo::DeleteInvite { code } => (
+ LightMethod::Delete,
+ Route::InvitesCode,
+ Cow::from(Route::invite(code)),
+ ),
+ RouteInfo::DeleteMessageReactions { channel_id, message_id } => (
+ LightMethod::Delete,
+ Route::ChannelsIdMessagesIdReactions(channel_id),
+ Cow::from(Route::channel_message_reactions(
+ channel_id,
+ message_id,
+ )),
+ ),
+ RouteInfo::DeleteMessage { channel_id, message_id } => (
+ LightMethod::Delete,
+ Route::ChannelsIdMessagesId(LightMethod::Delete, message_id),
+ Cow::from(Route::channel_message(channel_id, message_id)),
+ ),
+ RouteInfo::DeleteMessages { channel_id } => (
+ LightMethod::Delete,
+ Route::ChannelsIdMessagesBulkDelete(channel_id),
+ Cow::from(Route::channel_messages_bulk_delete(channel_id)),
+ ),
+ RouteInfo::DeletePermission { channel_id, target_id } => (
+ LightMethod::Delete,
+ Route::ChannelsIdPermissionsOverwriteId(channel_id),
+ Cow::from(Route::channel_permission(channel_id, target_id)),
+ ),
+ RouteInfo::DeleteReaction {
+ channel_id,
+ message_id,
+ reaction,
+ user,
+ } => (
+ LightMethod::Delete,
+ Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
+ Cow::from(Route::channel_message_reaction(
+ channel_id,
+ message_id,
+ user,
+ reaction,
+ ))
+ ),
+ RouteInfo::DeleteRole { guild_id, role_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdRolesId(guild_id),
+ Cow::from(Route::guild_role(guild_id, role_id)),
+ ),
+ RouteInfo::DeleteWebhook { webhook_id } => (
+ LightMethod::Delete,
+ Route::WebhooksId(webhook_id),
+ Cow::from(Route::webhook(webhook_id)),
+ ),
+ RouteInfo::DeleteWebhookWithToken { token, webhook_id } => (
+ LightMethod::Delete,
+ Route::WebhooksId(webhook_id),
+ Cow::from(Route::webhook_with_token(webhook_id, token)),
+ ),
+ RouteInfo::EditChannel { channel_id } => (
+ LightMethod::Patch,
+ Route::ChannelsId(channel_id),
+ Cow::from(Route::channel(channel_id)),
+ ),
+ RouteInfo::EditEmoji { emoji_id, guild_id } => (
+ LightMethod::Patch,
+ Route::GuildsIdEmojisId(guild_id),
+ Cow::from(Route::guild_emoji(guild_id, emoji_id)),
+ ),
+ RouteInfo::EditGuild { guild_id } => (
+ LightMethod::Patch,
+ Route::GuildsId(guild_id),
+ Cow::from(Route::guild(guild_id)),
+ ),
+ RouteInfo::EditGuildChannels { guild_id } => (
+ LightMethod::Patch,
+ Route::GuildsIdChannels(guild_id),
+ Cow::from(Route::guild_channels(guild_id)),
+ ),
+ RouteInfo::EditGuildEmbed { guild_id } => (
+ LightMethod::Patch,
+ Route::GuildsIdEmbed(guild_id),
+ Cow::from(Route::guild_embed(guild_id)),
+ ),
+ RouteInfo::EditMember { guild_id, user_id } => (
+ LightMethod::Patch,
+ Route::GuildsIdMembersId(guild_id),
+ Cow::from(Route::guild_member(guild_id, user_id)),
+ ),
+ RouteInfo::EditMessage { channel_id, message_id } => (
+ LightMethod::Patch,
+ Route::ChannelsIdMessagesId(LightMethod::Patch, channel_id),
+ Cow::from(Route::channel_message(channel_id, message_id)),
+ ),
+ RouteInfo::EditNickname { guild_id } => (
+ LightMethod::Patch,
+ Route::GuildsIdMembersMeNick(guild_id),
+ Cow::from(Route::guild_nickname(guild_id)),
+ ),
+ RouteInfo::EditProfile => (
+ LightMethod::Patch,
+ Route::UsersMe,
+ Cow::from(Route::user("@me")),
+ ),
+ RouteInfo::EditRole { guild_id, role_id } => (
+ LightMethod::Patch,
+ Route::GuildsIdRolesId(guild_id),
+ Cow::from(Route::guild_role(guild_id, role_id)),
+ ),
+ RouteInfo::EditWebhook { webhook_id } => (
+ LightMethod::Patch,
+ Route::WebhooksId(webhook_id),
+ Cow::from(Route::webhook(webhook_id)),
+ ),
+ RouteInfo::EditWebhookWithToken { token, webhook_id } => (
+ LightMethod::Patch,
+ Route::WebhooksId(webhook_id),
+ Cow::from(Route::webhook_with_token(webhook_id, token)),
+ ),
+ RouteInfo::ExecuteWebhook { token, wait, webhook_id } => (
+ LightMethod::Post,
+ Route::WebhooksId(webhook_id),
+ Cow::from(Route::webhook_with_token_optioned(
+ webhook_id,
+ token,
+ wait,
+ )),
+ ),
+ RouteInfo::GetActiveMaintenance => (
+ LightMethod::Get,
+ Route::None,
+ Cow::from(Route::status_maintenances_active()),
+ ),
+ RouteInfo::GetAuditLogs {
+ action_type,
+ before,
+ guild_id,
+ limit,
+ user_id,
+ } => (
+ LightMethod::Get,
+ Route::GuildsIdAuditLogs(guild_id),
+ Cow::from(Route::guild_audit_logs(
+ guild_id,
+ action_type,
+ user_id,
+ before,
+ limit,
+ )),
+ ),
+ RouteInfo::GetBans { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdBans(guild_id),
+ Cow::from(Route::guild_bans(guild_id)),
+ ),
+ RouteInfo::GetBotGateway => (
+ LightMethod::Get,
+ Route::GatewayBot,
+ Cow::from(Route::gateway_bot()),
+ ),
+ RouteInfo::GetChannel { channel_id } => (
+ LightMethod::Get,
+ Route::ChannelsId(channel_id),
+ Cow::from(Route::channel(channel_id)),
+ ),
+ RouteInfo::GetChannelInvites { channel_id } => (
+ LightMethod::Get,
+ Route::ChannelsIdInvites(channel_id),
+ Cow::from(Route::channel_invites(channel_id)),
+ ),
+ RouteInfo::GetChannelWebhooks { channel_id } => (
+ LightMethod::Get,
+ Route::ChannelsIdWebhooks(channel_id),
+ Cow::from(Route::channel_webhooks(channel_id)),
+ ),
+ RouteInfo::GetChannels { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdChannels(guild_id),
+ Cow::from(Route::guild_channels(guild_id)),
+ ),
+ RouteInfo::GetCurrentApplicationInfo => (
+ LightMethod::Get,
+ Route::None,
+ Cow::from(Route::oauth2_application_current()),
+ ),
+ RouteInfo::GetCurrentUser => (
+ LightMethod::Get,
+ Route::UsersMe,
+ Cow::from(Route::user("@me")),
+ ),
+ RouteInfo::GetGateway => (
+ LightMethod::Get,
+ Route::Gateway,
+ Cow::from(Route::gateway()),
+ ),
+ RouteInfo::GetGuild { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsId(guild_id),
+ Cow::from(Route::guild(guild_id)),
+ ),
+ RouteInfo::GetGuildEmbed { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdEmbed(guild_id),
+ Cow::from(Route::guild_embed(guild_id)),
+ ),
+ RouteInfo::GetGuildIntegrations { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdIntegrations(guild_id),
+ Cow::from(Route::guild_integrations(guild_id)),
+ ),
+ RouteInfo::GetGuildInvites { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdInvites(guild_id),
+ Cow::from(Route::guild_invites(guild_id)),
+ ),
+ RouteInfo::GetGuildMembers { after, guild_id, limit } => (
+ LightMethod::Get,
+ Route::GuildsIdMembers(guild_id),
+ Cow::from(Route::guild_members_optioned(guild_id, after, limit)),
+ ),
+ RouteInfo::GetGuildPruneCount { days, guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdPrune(guild_id),
+ Cow::from(Route::guild_prune(guild_id, days)),
+ ),
+ RouteInfo::GetGuildRegions { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdRegions(guild_id),
+ Cow::from(Route::guild_regions(guild_id)),
+ ),
+ RouteInfo::GetGuildRoles { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdRoles(guild_id),
+ Cow::from(Route::guild_roles(guild_id)),
+ ),
+ RouteInfo::GetGuildVanityUrl { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdVanityUrl(guild_id),
+ Cow::from(Route::guild_vanity_url(guild_id)),
+ ),
+ RouteInfo::GetGuildWebhooks { guild_id } => (
+ LightMethod::Get,
+ Route::GuildsIdWebhooks(guild_id),
+ Cow::from(Route::guild_webhooks(guild_id)),
+ ),
+ RouteInfo::GetGuilds { after, before, limit } => (
+ LightMethod::Get,
+ Route::UsersMeGuilds,
+ Cow::from(Route::user_guilds_optioned(
+ "@me",
+ after,
+ before,
+ limit,
+ )),
+ ),
+ RouteInfo::GetInvite { code, stats } => (
+ LightMethod::Get,
+ Route::InvitesCode,
+ Cow::from(Route::invite_optioned(code, stats)),
+ ),
+ RouteInfo::GetMember { guild_id, user_id } => (
+ LightMethod::Get,
+ Route::GuildsIdMembersId(guild_id),
+ Cow::from(Route::guild_member(guild_id, user_id)),
+ ),
+ RouteInfo::GetMessage { channel_id, message_id } => (
+ LightMethod::Get,
+ Route::ChannelsIdMessagesId(LightMethod::Get, channel_id),
+ Cow::from(Route::channel_message(channel_id, message_id)),
+ ),
+ RouteInfo::GetMessages { channel_id, ref query } => (
+ LightMethod::Get,
+ Route::ChannelsIdMessages(channel_id),
+ Cow::from(Route::channel_messages(
+ channel_id,
+ Some(query.as_ref()),
+ )),
+ ),
+ RouteInfo::GetPins { channel_id } => (
+ LightMethod::Get,
+ Route::ChannelsIdPins(channel_id),
+ Cow::from(Route::channel_pins(channel_id)),
+ ),
+ RouteInfo::GetReactionUsers {
+ after,
+ channel_id,
+ limit,
+ message_id,
+ ref reaction,
+ } => (
+ LightMethod::Get,
+ Route::ChannelsIdMessagesIdReactions(channel_id),
+ Cow::from(Route::channel_message_reactions_list(
+ channel_id,
+ message_id,
+ reaction,
+ limit,
+ after,
+ )),
+ ),
+ RouteInfo::GetUnresolvedIncidents => (
+ LightMethod::Get,
+ Route::None,
+ Cow::from(Route::status_incidents_unresolved()),
+ ),
+ RouteInfo::GetUpcomingMaintenances => (
+ LightMethod::Get,
+ Route::None,
+ Cow::from(Route::status_maintenances_upcoming()),
+ ),
+ RouteInfo::GetUser { user_id } => (
+ LightMethod::Get,
+ Route::UsersId,
+ Cow::from(Route::user(user_id)),
+ ),
+ RouteInfo::GetUserDmChannels => (
+ LightMethod::Get,
+ Route::UsersMeChannels,
+ Cow::from(Route::user_dm_channels("@me")),
+ ),
+ RouteInfo::GetVoiceRegions => (
+ LightMethod::Get,
+ Route::VoiceRegions,
+ Cow::from(Route::voice_regions()),
+ ),
+ RouteInfo::GetWebhook { webhook_id } => (
+ LightMethod::Get,
+ Route::WebhooksId(webhook_id),
+ Cow::from(Route::webhook(webhook_id)),
+ ),
+ RouteInfo::GetWebhookWithToken { token, webhook_id } => (
+ LightMethod::Get,
+ Route::WebhooksId(webhook_id),
+ Cow::from(Route::webhook_with_token(webhook_id, token)),
+ ),
+ RouteInfo::KickMember { guild_id, user_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdMembersId(guild_id),
+ Cow::from(Route::guild_member(guild_id, user_id)),
+ ),
+ RouteInfo::LeaveGroup { group_id } => (
+ LightMethod::Delete,
+ Route::ChannelsId(group_id),
+ Cow::from(Route::channel(group_id)),
+ ),
+ RouteInfo::LeaveGuild { guild_id } => (
+ LightMethod::Delete,
+ Route::UsersMeGuildsId,
+ Cow::from(Route::user_guild("@me", guild_id)),
+ ),
+ RouteInfo::RemoveGroupRecipient { group_id, user_id } => (
+ LightMethod::Delete,
+ Route::None,
+ Cow::from(Route::group_recipient(group_id, user_id)),
+ ),
+ RouteInfo::PinMessage { channel_id, message_id } => (
+ LightMethod::Put,
+ Route::ChannelsIdPins(channel_id),
+ Cow::from(Route::channel_pin(channel_id, message_id)),
+ ),
+ RouteInfo::RemoveBan { guild_id, user_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdBansUserId(guild_id),
+ Cow::from(Route::guild_ban(guild_id, user_id)),
+ ),
+ RouteInfo::RemoveMemberRole { guild_id, role_id, user_id } => (
+ LightMethod::Delete,
+ Route::GuildsIdMembersIdRolesId(guild_id),
+ Cow::from(Route::guild_member_role(guild_id, user_id, role_id)),
+ ),
+ RouteInfo::StartGuildPrune { days, guild_id } => (
+ LightMethod::Post,
+ Route::GuildsIdPrune(guild_id),
+ Cow::from(Route::guild_prune(guild_id, days)),
+ ),
+ RouteInfo::StartIntegrationSync { guild_id, integration_id } => (
+ LightMethod::Post,
+ Route::GuildsIdIntegrationsId(guild_id),
+ Cow::from(Route::guild_integration_sync(
+ guild_id,
+ integration_id,
+ )),
+ ),
+ RouteInfo::StatusIncidentsUnresolved => (
+ LightMethod::Get,
+ Route::None,
+ Cow::from(Route::status_incidents_unresolved()),
+ ),
+ RouteInfo::StatusMaintenancesActive => (
+ LightMethod::Get,
+ Route::None,
+ Cow::from(Route::status_maintenances_active()),
+ ),
+ RouteInfo::StatusMaintenancesUpcoming => (
+ LightMethod::Get,
+ Route::None,
+ Cow::from(Route::status_maintenances_upcoming()),
+ ),
+ RouteInfo::UnpinMessage { channel_id, message_id } => (
+ LightMethod::Delete,
+ Route::ChannelsIdPinsMessageId(channel_id),
+ Cow::from(Route::channel_pin(channel_id, message_id)),
+ ),
+ }
+ }
+}