aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2017-02-12 09:23:07 -0800
committerZeyla Hellyer <[email protected]>2017-02-12 09:23:07 -0800
commit01f687204dd9d5564ec4bdc860f11bfd5e01454f (patch)
treeb7b14cf34418cf8265e1a0d1fabf6b54335103ff /src
parentHandle unsuccessful responses before decoding (diff)
downloadserenity-01f687204dd9d5564ec4bdc860f11bfd5e01454f.tar.xz
serenity-01f687204dd9d5564ec4bdc860f11bfd5e01454f.zip
Uniquely ratelimit message deletions
Message deletions fall under a separate ratelimit apart from the route's global ratelimit, and so the DELETE verb for the route is now separately handled. This is documented [here] as the following (at the time of this writing): > There is currently a single exception to the above rule regarding > different HTTP methods sharing the same rate limit, and that is for > the deletion of messages. Deleting messages falls under a separate, > higher rate limit so that bots are able to more quickly delete content > from channels (which is useful for moderation bots). [here]: https://discordapp.com/developers/docs/topics/rate-limits#rate-limits
Diffstat (limited to 'src')
-rw-r--r--src/client/rest/mod.rs25
-rw-r--r--src/client/rest/ratelimiting.rs10
2 files changed, 30 insertions, 5 deletions
diff --git a/src/client/rest/mod.rs b/src/client/rest/mod.rs
index 253f0f9..a49ba43 100644
--- a/src/client/rest/mod.rs
+++ b/src/client/rest/mod.rs
@@ -49,6 +49,25 @@ use ::internal::prelude::*;
use ::model::*;
use ::utils::decode_array;
+/// An method used for ratelimiting special routes.
+///
+/// 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.
+ Get,
+ /// Indicates that a route is for the `PATCH` method only.
+ Patch,
+ /// Indicates that a route is for the `POST` method only.
+ Post,
+ /// Indicates that a route is for the `PUT` method only.
+ Put,
+}
+
lazy_static! {
static ref TOKEN: Arc<Mutex<String>> = Arc::new(Mutex::new(String::default()));
}
@@ -450,7 +469,7 @@ pub fn delete_invite(code: &str) -> Result<Invite> {
/// Deletes a message if created by us or we have
/// specific permissions.
pub fn delete_message(channel_id: u64, message_id: u64) -> Result<()> {
- verify(204, request!(Route::ChannelsIdMessagesId(channel_id),
+ verify(204, request!(Route::ChannelsIdMessagesId(LightMethod::Delete, channel_id),
delete,
"/channels/{}/messages/{}",
channel_id,
@@ -641,7 +660,7 @@ pub fn edit_member(guild_id: u64, user_id: u64, map: Value) -> 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_string(&map)?;
- let response = request!(Route::ChannelsIdMessagesId(channel_id),
+ let response = request!(Route::ChannelsIdMessagesId(LightMethod::Any, channel_id),
patch(body),
"/channels/{}/messages/{}",
channel_id,
@@ -1197,7 +1216,7 @@ pub fn get_member(guild_id: u64, user_id: u64) -> Result<Member> {
/// Gets a message by an Id, bots only.
pub fn get_message(channel_id: u64, message_id: u64) -> Result<Message> {
- let response = request!(Route::ChannelsIdMessagesId(channel_id),
+ let response = request!(Route::ChannelsIdMessagesId(LightMethod::Any, channel_id),
get,
"/channels/{}/messages/{}",
channel_id,
diff --git a/src/client/rest/ratelimiting.rs b/src/client/rest/ratelimiting.rs
index 26f35d6..f232759 100644
--- a/src/client/rest/ratelimiting.rs
+++ b/src/client/rest/ratelimiting.rs
@@ -46,6 +46,7 @@ use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{str, thread};
+use super::LightMethod;
use time;
use ::internal::prelude::*;
@@ -101,7 +102,13 @@ pub enum Route {
ChannelsIdInvites(u64),
ChannelsIdMessages(u64),
ChannelsIdMessagesBulkDelete(u64),
- ChannelsIdMessagesId(u64),
+ // 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.
+ //
+ // [Rate Limits]: https://discordapp.com/developers/docs/topics/rate-limits
+ ChannelsIdMessagesId(LightMethod, u64),
ChannelsIdMessagesIdAck(u64),
ChannelsIdMessagesIdReactions(u64),
ChannelsIdMessagesIdReactionsUserIdType(u64),
@@ -150,7 +157,6 @@ pub enum Route {
#[doc(hidden)]
pub fn perform<'a, F>(route: Route, f: F) -> Result<Response>
where F: Fn() -> RequestBuilder<'a> {
-
loop {
{
// This will block if another thread already has the global