Skip to main content

strife/http/
routing.rs

1//! Routing for the Discord REST API.
2//!
3//! Not part of the public API.
4
5use std::borrow::Cow;
6use std::fmt::Write;
7
8use hyper::Method as HttpMethod;
9
10use crate::model::channel::permissions::OverwriteId;
11use crate::model::guild::{AuditLogEvent, Emoji};
12use crate::model::id::*;
13
14/// Buckets grouping [rate limited] routes.
15///
16/// [rate limited]: https://discordapp.com/developers/docs/topics/rate-limits#rate-limits
17#[non_exhaustive]
18#[remain::sorted]
19#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20pub enum Bucket {
21    /// Route:
22    /// ```text
23    /// /channels/{channel.id}
24    /// ```
25    ChannelsId(ChannelId),
26    /// Route:
27    /// ```text
28    /// /channels/{channel.id}/invites
29    /// ```
30    ChannelsIdInvites(ChannelId),
31    /// Route:
32    /// ```text
33    /// /channels/{channel.id}/messages
34    /// ```
35    ChannelsIdMessages(ChannelId),
36    /// Route:
37    /// ```text
38    /// /channels/{channel.id}/messages/bulk-delete
39    /// ```
40    ChannelsIdMessagesBulkDelete(ChannelId),
41    /// Route:
42    /// ```text
43    /// /channels/{channel.id}/messages/{message.id}
44    /// ```
45    ChannelsIdMessagesId(ChannelId),
46    /// Route:
47    /// ```text
48    /// /channels/{channel.id}/messages/{message.id}
49    /// ```
50    ///
51    /// This has a separate bucket from [`ChannelsIdMessagesId`]. From the
52    /// Discord docs:
53    ///
54    /// > Deleting messages falls under a separate, higher rate limit so that
55    /// > bots are able to more quickly delete content from channels (which is
56    /// > useful for moderation bots).
57    ///
58    /// [`ChannelsIdMessagesId`]: enum.Bucket.html#variant.ChannelsIdMessagesId
59    ChannelsIdMessagesIdDelete(ChannelId),
60    /// Route:
61    /// ```text
62    /// /channels/{channel.id}/messages/{message.id}/reactions
63    /// ```
64    ChannelsIdMessagesIdReactions(ChannelId),
65    /// Route:
66    /// ```text
67    /// /channels/{channel.id}/messages/{message.id}/reactions/{emoji}
68    /// ```
69    ChannelsIdMessagesIdReactionsEmoji(ChannelId),
70    /// Routes:
71    /// ```text
72    /// /channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me
73    /// /channels/{channel.id}/messages/{message.id}/reactions/{emoji}/{user.id}
74    /// ```
75    ChannelsIdMessagesIdReactionsEmojiUserId(ChannelId),
76    /// Route:
77    /// ```text
78    /// /channels/{channel.id}/permissions/{overwrite.id}
79    /// ```
80    ChannelsIdPermissionsOverwriteId(ChannelId),
81    /// Route:
82    /// ```text
83    /// /channels/{channel.id}/pins
84    /// ```
85    ChannelsIdPins(ChannelId),
86    /// Route:
87    /// ```text
88    /// /channels/{channel.id}/pins/{message.id}
89    /// ```
90    ChannelsIdPinsMessageId(ChannelId),
91    /// Route:
92    /// ```text
93    /// /channels/{channel.id}/recipients/{user.id}
94    /// ```
95    ChannelsIdRecipientsUserId(ChannelId),
96    /// Route:
97    /// ```text
98    /// /channels/{channel.id}/typing
99    /// ```
100    ChannelsIdTyping(ChannelId),
101    /// Route:
102    /// ```text
103    /// /channels/{channel.id}/webhooks
104    /// ```
105    ChannelsIdWebhooks(ChannelId),
106
107    /// Route:
108    /// ```text
109    /// /gateway
110    /// ```
111    Gateway,
112    /// Route:
113    /// ```text
114    /// /gateway/bot
115    /// ```
116    GatewayBot,
117    /// Route:
118    /// ```text
119    /// /guilds
120    /// ```
121    Guilds,
122    /// Route:
123    /// ```text
124    /// /guilds/{guild.id}
125    /// ```
126    GuildsId(GuildId),
127    /// Route:
128    /// ```text
129    /// /guild/{guild.id}/audit-logs
130    /// ```
131    GuildsIdAuditLogs(GuildId),
132    /// Route:
133    /// ```text
134    /// /guilds/{guild.id}/bans
135    /// ```
136    GuildsIdBans(GuildId),
137    /// Route:
138    /// ```text
139    /// /guilds/{guild.id}/bans/{user.id}
140    /// ```
141    GuildsIdBansUserId(GuildId),
142    /// Route:
143    /// ```text
144    /// /guilds/{guild.id}/channels
145    /// ```
146    GuildsIdChannels(GuildId),
147    /// Route:
148    /// ```text
149    /// /guilds/{guild.id}/embed
150    /// ```
151    GuildsIdEmbed(GuildId),
152    /// Route:
153    /// ```text
154    /// /guilds/{guild.id}/emojis
155    /// ```
156    GuildsIdEmojis(GuildId),
157    /// Route:
158    /// ```text
159    /// /guilds/{guild.id}/emojis/{emoji.id}
160    /// ```
161    GuildsIdEmojisId(GuildId),
162    /// Route:
163    /// ```text
164    /// /guilds/{guild.id}/integrations
165    /// ```
166    GuildsIdIntegrations(GuildId),
167    /// Route:
168    /// ```text
169    /// /guilds/{guild.id}/integrations/{integration.id}
170    /// ```
171    GuildsIdIntegrationsId(GuildId),
172    /// Route:
173    /// ```text
174    /// /guilds/{guild.id}/integrations/{integration.id}/sync
175    /// ```
176    GuildsIdIntegrationsIdSync(GuildId),
177    /// Route:
178    /// ```text
179    /// /guilds/{guild.id}/invites
180    /// ```
181    GuildsIdInvites(GuildId),
182    /// Route:
183    /// ```text
184    /// /guilds/{guild.id}/members
185    /// ```
186    GuildsIdMembers(GuildId),
187    /// Route:
188    /// ```text
189    /// /guilds/{guild.id}/members/{user.id}
190    /// ```
191    GuildsIdMembersId(GuildId),
192    /// Route:
193    /// ```text
194    /// /guilds/{guild.id}/members/{user.id}/roles/{role.id}
195    /// ```
196    GuildsIdMembersIdRolesId(GuildId),
197    /// Route:
198    /// ```text
199    /// /guilds/{guild.id}/members/@me/nick
200    /// ```
201    GuildsIdMembersMeNick(GuildId),
202    /// Route:
203    /// ```text
204    /// /guilds/{guild.id}/prune
205    /// ```
206    GuildsIdPrune(GuildId),
207    /// Route:
208    /// ```text
209    /// /guilds/{guild.id}/regions
210    /// ```
211    GuildsIdRegions(GuildId),
212    /// Route:
213    /// ```text
214    /// /guilds/{guild.id}/roles
215    /// ```
216    GuildsIdRoles(GuildId),
217    /// Route:
218    /// ```text
219    /// /guilds/{guild.id}/roles/{role.id}
220    /// ```
221    GuildsIdRolesId(GuildId),
222    /// Route:
223    /// ```text
224    /// /guilds/{guild.id}/vanity-url
225    /// ```
226    GuildsIdVanityUrl(GuildId),
227    /// Route:
228    /// ```text
229    /// /guilds/{guild.id}/webhooks
230    /// ```
231    GuildsIdWebhooks(GuildId),
232
233    /// Route:
234    /// ```text
235    /// /invites/{invite.code}
236    /// ```
237    InvitesCode,
238
239    /// Route:
240    /// ```text
241    /// /users/@me
242    /// /users/{user.id}
243    /// ```
244    UsersId,
245    /// Route:
246    /// ```text
247    /// /users/@me/channels
248    /// ```
249    UsersMeChannels,
250    /// Route:
251    /// ```text
252    /// /users/@me/guilds
253    /// ```
254    UsersMeGuilds,
255    /// Route:
256    /// ```text
257    /// /users/@me/guilds/{guild.id}
258    /// ```
259    UsersMeGuildsId(GuildId),
260
261    /// Route:
262    /// ```text
263    /// /voice/regions
264    /// ```
265    VoiceRegions,
266
267    /// Route:
268    /// ```text
269    /// /webhooks/{webhook.id}
270    /// ```
271    WebhooksId(WebhookId),
272    /// Route:
273    /// ```text
274    /// /webhooks/{webhook.id}/{webhook.token}
275    /// ```
276    WebhooksIdToken(WebhookId),
277
278    /// Routes where no rate limits are in place.
279    #[remain::unsorted]
280    None,
281}
282
283// TODO: Add support for status api (https://status.discordapp.com/api/).
284/// An API endpoint.
285///
286/// # Stability
287///
288/// This is not part of the stable API and may change at any time. For a stable
289/// API use the functions on the [`Http`] client.
290///
291/// [`Http`]: ../struct.Http.html
292#[allow(missing_docs)]
293#[non_exhaustive]
294#[remain::sorted]
295#[derive(Clone, Debug)]
296pub enum Route<'a> {
297    AddGroupRecipient {
298        channel_id: ChannelId,
299        user_id: UserId,
300    },
301    AddMemberRole {
302        guild_id: GuildId,
303        user_id: UserId,
304        role_id: RoleId,
305    },
306    BanMember {
307        guild_id: GuildId,
308        user_id: UserId,
309        delete_message_days: Option<u8>,
310        reason: Option<&'a str>,
311    },
312    BroadcastTyping {
313        channel_id: ChannelId,
314    },
315    CreateChannel {
316        guild_id: GuildId,
317    },
318    CreateChannelWebhook {
319        channel_id: ChannelId,
320    },
321    CreateEmoji {
322        guild_id: GuildId,
323    },
324    CreateGuild,
325    CreateIntegration {
326        guild_id: GuildId,
327    },
328    CreateInvite {
329        channel_id: ChannelId,
330    },
331    CreateMessage {
332        channel_id: ChannelId,
333    },
334    CreatePrivateChannel,
335    CreateReaction {
336        channel_id: ChannelId,
337        message_id: MessageId,
338        emoji: Emoji,
339    },
340    CreateRole {
341        guild_id: GuildId,
342    },
343    DeleteChannel {
344        channel_id: ChannelId,
345    },
346    DeleteChannelPermission {
347        channel_id: ChannelId,
348        overwrite_id: OverwriteId,
349    },
350    DeleteEmoji {
351        guild_id: GuildId,
352        emoji_id: EmojiId,
353    },
354    DeleteGuild {
355        guild_id: GuildId,
356    },
357    DeleteIntegration {
358        guild_id: GuildId,
359        integration_id: IntegrationId,
360    },
361    DeleteInvite {
362        code: &'a str,
363    },
364    DeleteMessage {
365        channel_id: ChannelId,
366        message_id: MessageId,
367    },
368    DeleteMessagesBulk {
369        channel_id: ChannelId,
370    },
371    DeleteOwnReaction {
372        channel_id: ChannelId,
373        message_id: MessageId,
374        emoji: Emoji,
375    },
376    DeleteReaction {
377        channel_id: ChannelId,
378        message_id: MessageId,
379        emoji: Emoji,
380        user_id: UserId,
381    },
382    DeleteReactions {
383        channel_id: ChannelId,
384        message_id: MessageId,
385    },
386    DeleteRole {
387        guild_id: GuildId,
388        role_id: RoleId,
389    },
390    DeleteWebhook {
391        webhook_id: WebhookId,
392    },
393    DeleteWebhookWithToken {
394        webhook_id: WebhookId,
395        token: &'a str,
396    },
397    EditChannel {
398        channel_id: ChannelId,
399    },
400    EditChannelPermission {
401        channel_id: ChannelId,
402        overwrite_id: OverwriteId,
403    },
404    EditChannelPositions {
405        guild_id: GuildId,
406    },
407    EditCurrentUser,
408    EditEmoji {
409        guild_id: GuildId,
410        emoji_id: EmojiId,
411    },
412    EditGuild {
413        guild_id: GuildId,
414    },
415    EditGuildEmbed {
416        guild_id: GuildId,
417    },
418    EditIntegration {
419        guild_id: GuildId,
420        integration_id: IntegrationId,
421    },
422    EditMember {
423        guild_id: GuildId,
424        user_id: UserId,
425    },
426    EditMessage {
427        channel_id: ChannelId,
428        message_id: MessageId,
429    },
430    EditNickname {
431        guild_id: GuildId,
432    },
433    EditRole {
434        guild_id: GuildId,
435        role_id: RoleId,
436    },
437    EditRolePositions {
438        guild_id: GuildId,
439    },
440    EditWebhook {
441        webhook_id: WebhookId,
442    },
443    EditWebhookWithToken {
444        webhook_id: WebhookId,
445        token: &'a str,
446    },
447    ExecuteWebhook {
448        webhook_id: WebhookId,
449        token: &'a str,
450        wait: Option<bool>,
451    },
452    GetAuditLogs {
453        guild_id: GuildId,
454        user_id: Option<UserId>,
455        action_type: Option<AuditLogEvent>,
456        before: Option<AuditLogEntryId>,
457        limit: Option<u8>,
458    },
459    GetBan {
460        guild_id: GuildId,
461        user_id: UserId,
462    },
463    GetBans {
464        guild_id: GuildId,
465    },
466    GetBotGateway,
467    GetChannel {
468        channel_id: ChannelId,
469    },
470    GetChannels {
471        guild_id: GuildId,
472    },
473    GetChannelWebhooks {
474        channel_id: ChannelId,
475    },
476    GetCurrentUser,
477    GetCurrentUserGuilds,
478    GetEmoji {
479        guild_id: GuildId,
480        emoji_id: EmojiId,
481    },
482    GetGateway,
483    GetGuild {
484        guild_id: GuildId,
485    },
486    GetGuildEmbed {
487        guild_id: GuildId,
488    },
489    GetGuildEmojis {
490        guild_id: GuildId,
491    },
492    GetGuildIntegrations {
493        guild_id: GuildId,
494    },
495    GetGuildInvites {
496        guild_id: GuildId,
497    },
498    GetGuildMembers {
499        guild_id: GuildId,
500        limit: Option<u16>,
501        after: Option<UserId>,
502    },
503    GetGuildPruneCount {
504        guild_id: GuildId,
505        days: Option<u64>,
506    },
507    GetGuildRegions {
508        guild_id: GuildId,
509    },
510    GetGuildVanityUrl {
511        guild_id: GuildId,
512    },
513    GetGuildWebhooks {
514        guild_id: GuildId,
515    },
516    GetInvite {
517        code: &'a str,
518        with_counts: Option<bool>,
519    },
520    GetInvites {
521        channel_id: ChannelId,
522    },
523    GetMember {
524        guild_id: GuildId,
525        user_id: UserId,
526    },
527    GetMessage {
528        channel_id: ChannelId,
529        message_id: MessageId,
530    },
531    GetMessages {
532        channel_id: ChannelId,
533        // The keys (before, after, and around) are mutually exclusive.
534        // Use an enum to simulate this behaviour.
535        around: Option<AroundMessage>,
536        limit: Option<u8>,
537    },
538    GetPins {
539        channel_id: ChannelId,
540    },
541    GetReactionUsers {
542        channel_id: ChannelId,
543        message_id: MessageId,
544        emoji: Emoji,
545        before: Option<UserId>,
546        after: Option<UserId>,
547        limit: Option<u8>,
548    },
549    GetRoles {
550        guild_id: GuildId,
551    },
552    GetUser {
553        user_id: UserId,
554    },
555    GetVoiceRegions,
556    GetWebhook {
557        webhook_id: WebhookId,
558    },
559    GetWebhookWithToken {
560        webhook_id: WebhookId,
561        token: &'a str,
562    },
563    KickMember {
564        guild_id: GuildId,
565        user_id: UserId,
566    },
567    LeaveGuild {
568        guild_id: GuildId,
569    },
570    PinMessage {
571        channel_id: ChannelId,
572        message_id: MessageId,
573    },
574    PruneGuildMembers {
575        guild_id: GuildId,
576        days: Option<u64>,
577        compute_prune_count: Option<bool>,
578    },
579    RemoveGroupRecipient {
580        channel_id: ChannelId,
581        user_id: UserId,
582    },
583    RemoveMemberRole {
584        guild_id: GuildId,
585        user_id: UserId,
586        role_id: RoleId,
587    },
588    SyncIntegration {
589        guild_id: GuildId,
590        integration_id: IntegrationId,
591    },
592    UnbanMember {
593        guild_id: GuildId,
594        user_id: UserId,
595    },
596    UnpinMessage {
597        channel_id: ChannelId,
598        message_id: MessageId,
599    },
600}
601
602impl<'a> Route<'a> {
603    #[remain::check]
604    pub(crate) fn method(&self) -> Method {
605        use self::Route::*;
606
607        #[remain::sorted]
608        match self {
609            AddGroupRecipient { .. } => Method::Put,
610            AddMemberRole { .. } => Method::Put,
611            BanMember { .. } => Method::Put,
612            BroadcastTyping { .. } => Method::Post,
613            CreateChannel { .. } => Method::Post,
614            CreateChannelWebhook { .. } => Method::Post,
615            CreateEmoji { .. } => Method::Post,
616            CreateGuild => Method::Post,
617            CreateIntegration { .. } => Method::Post,
618            CreateInvite { .. } => Method::Post,
619            CreateMessage { .. } => Method::Post,
620            CreatePrivateChannel => Method::Post,
621            CreateReaction { .. } => Method::Put,
622            CreateRole { .. } => Method::Post,
623            DeleteChannel { .. } => Method::Delete,
624            DeleteChannelPermission { .. } => Method::Delete,
625            DeleteEmoji { .. } => Method::Delete,
626            DeleteGuild { .. } => Method::Delete,
627            DeleteIntegration { .. } => Method::Delete,
628            DeleteInvite { .. } => Method::Delete,
629            DeleteMessage { .. } => Method::Delete,
630            DeleteMessagesBulk { .. } => Method::Delete,
631            DeleteOwnReaction { .. } => Method::Delete,
632            DeleteReaction { .. } => Method::Delete,
633            DeleteReactions { .. } => Method::Delete,
634            DeleteRole { .. } => Method::Delete,
635            DeleteWebhook { .. } => Method::Delete,
636            DeleteWebhookWithToken { .. } => Method::Delete,
637            EditChannel { .. } => Method::Patch,
638            EditChannelPermission { .. } => Method::Put,
639            EditChannelPositions { .. } => Method::Patch,
640            EditCurrentUser => Method::Patch,
641            EditEmoji { .. } => Method::Patch,
642            EditGuild { .. } => Method::Patch,
643            EditGuildEmbed { .. } => Method::Patch,
644            EditIntegration { .. } => Method::Patch,
645            EditMember { .. } => Method::Patch,
646            EditMessage { .. } => Method::Patch,
647            EditNickname { .. } => Method::Patch,
648            EditRole { .. } => Method::Patch,
649            EditRolePositions { .. } => Method::Patch,
650            EditWebhook { .. } => Method::Patch,
651            EditWebhookWithToken { .. } => Method::Patch,
652            ExecuteWebhook { .. } => Method::Post,
653            GetAuditLogs { .. } => Method::Get,
654            GetBan { .. } => Method::Get,
655            GetBans { .. } => Method::Get,
656            GetBotGateway => Method::Get,
657            GetChannel { .. } => Method::Get,
658            GetChannels { .. } => Method::Get,
659            GetChannelWebhooks { .. } => Method::Get,
660            GetCurrentUser => Method::Get,
661            GetCurrentUserGuilds => Method::Get,
662            GetEmoji { .. } => Method::Get,
663            GetGateway => Method::Get,
664            GetGuild { .. } => Method::Get,
665            GetGuildEmbed { .. } => Method::Get,
666            GetGuildEmojis { .. } => Method::Get,
667            GetGuildIntegrations { .. } => Method::Get,
668            GetGuildInvites { .. } => Method::Get,
669            GetGuildMembers { .. } => Method::Get,
670            GetGuildPruneCount { .. } => Method::Get,
671            GetGuildRegions { .. } => Method::Get,
672            GetGuildVanityUrl { .. } => Method::Get,
673            GetGuildWebhooks { .. } => Method::Get,
674            GetInvite { .. } => Method::Get,
675            GetInvites { .. } => Method::Get,
676            GetMember { .. } => Method::Get,
677            GetMessage { .. } => Method::Get,
678            GetMessages { .. } => Method::Get,
679            GetPins { .. } => Method::Get,
680            GetReactionUsers { .. } => Method::Get,
681            GetRoles { .. } => Method::Get,
682            GetUser { .. } => Method::Get,
683            GetVoiceRegions => Method::Get,
684            GetWebhook { .. } => Method::Get,
685            GetWebhookWithToken { .. } => Method::Get,
686            KickMember { .. } => Method::Delete,
687            LeaveGuild { .. } => Method::Delete,
688            PinMessage { .. } => Method::Put,
689            PruneGuildMembers { .. } => Method::Post,
690            RemoveGroupRecipient { .. } => Method::Delete,
691            RemoveMemberRole { .. } => Method::Delete,
692            SyncIntegration { .. } => Method::Post,
693            UnbanMember { .. } => Method::Delete,
694            UnpinMessage { .. } => Method::Delete,
695        }
696    }
697
698    pub(crate) fn bucket(&self) -> Bucket {
699        use self::Route::*;
700
701        match *self {
702            GetAuditLogs { guild_id, .. } => Bucket::GuildsIdAuditLogs(guild_id),
703
704            GetChannel { channel_id }
705            | EditChannel { channel_id }
706            | DeleteChannel { channel_id } => Bucket::ChannelsId(channel_id),
707
708            GetMessages { channel_id, .. } | CreateMessage { channel_id } => {
709                Bucket::ChannelsIdMessages(channel_id)
710            }
711
712            GetMessage { channel_id, .. } => Bucket::ChannelsIdMessagesId(channel_id),
713
714            CreateReaction { channel_id, .. }
715            | DeleteReaction { channel_id, .. }
716            | DeleteOwnReaction { channel_id, .. } => {
717                Bucket::ChannelsIdMessagesIdReactionsEmojiUserId(channel_id)
718            }
719
720            GetReactionUsers { channel_id, .. } => {
721                Bucket::ChannelsIdMessagesIdReactionsEmoji(channel_id)
722            }
723
724            DeleteReactions { channel_id, .. } => Bucket::ChannelsIdMessagesIdReactions(channel_id),
725
726            EditMessage { channel_id, .. } => Bucket::ChannelsIdMessagesId(channel_id),
727            DeleteMessage { channel_id, .. } => Bucket::ChannelsIdMessagesIdDelete(channel_id),
728
729            DeleteMessagesBulk { channel_id, .. } => {
730                Bucket::ChannelsIdMessagesBulkDelete(channel_id)
731            }
732
733            EditChannelPermission { channel_id, .. }
734            | DeleteChannelPermission { channel_id, .. } => {
735                Bucket::ChannelsIdPermissionsOverwriteId(channel_id)
736            }
737
738            GetInvites { channel_id } | CreateInvite { channel_id } => {
739                Bucket::ChannelsIdInvites(channel_id)
740            }
741
742            BroadcastTyping { channel_id } => Bucket::ChannelsIdTyping(channel_id),
743
744            GetPins { channel_id } => Bucket::ChannelsIdPins(channel_id),
745
746            PinMessage { channel_id, .. } | UnpinMessage { channel_id, .. } => {
747                Bucket::ChannelsIdPinsMessageId(channel_id)
748            }
749
750            AddGroupRecipient { channel_id, .. } | RemoveGroupRecipient { channel_id, .. } => {
751                Bucket::ChannelsIdRecipientsUserId(channel_id)
752            }
753
754            GetGuildEmojis { guild_id } | CreateEmoji { guild_id } => {
755                Bucket::GuildsIdEmojis(guild_id)
756            }
757
758            GetEmoji { guild_id, .. }
759            | EditEmoji { guild_id, .. }
760            | DeleteEmoji { guild_id, .. } => Bucket::GuildsIdEmojisId(guild_id),
761
762            CreateGuild => Bucket::Guilds,
763
764            GetGuild { guild_id } | EditGuild { guild_id } | DeleteGuild { guild_id } => {
765                Bucket::GuildsId(guild_id)
766            }
767
768            GetChannels { guild_id }
769            | CreateChannel { guild_id }
770            | EditChannelPositions { guild_id } => Bucket::GuildsIdChannels(guild_id),
771
772            GetMember { guild_id, .. }
773            | EditMember { guild_id, .. }
774            | KickMember { guild_id, .. } => Bucket::GuildsIdMembersId(guild_id),
775
776            GetGuildMembers { guild_id, .. } => Bucket::GuildsIdMembers(guild_id),
777
778            EditNickname { guild_id, .. } => Bucket::GuildsIdMembersMeNick(guild_id),
779
780            AddMemberRole { guild_id, .. } | RemoveMemberRole { guild_id, .. } => {
781                Bucket::GuildsIdMembersIdRolesId(guild_id)
782            }
783
784            GetBans { guild_id } => Bucket::GuildsIdBans(guild_id),
785
786            GetBan { guild_id, .. } | BanMember { guild_id, .. } | UnbanMember { guild_id, .. } => {
787                Bucket::GuildsIdBansUserId(guild_id)
788            }
789
790            GetRoles { guild_id } | CreateRole { guild_id } | EditRolePositions { guild_id } => {
791                Bucket::GuildsIdRoles(guild_id)
792            }
793
794            EditRole { guild_id, .. } | DeleteRole { guild_id, .. } => {
795                Bucket::GuildsIdRolesId(guild_id)
796            }
797
798            GetGuildPruneCount { guild_id, .. } | PruneGuildMembers { guild_id, .. } => {
799                Bucket::GuildsIdPrune(guild_id)
800            }
801
802            GetGuildRegions { guild_id } => Bucket::GuildsIdRegions(guild_id),
803
804            GetGuildInvites { guild_id } => Bucket::GuildsIdInvites(guild_id),
805
806            GetGuildIntegrations { guild_id } | CreateIntegration { guild_id } => {
807                Bucket::GuildsIdIntegrations(guild_id)
808            }
809
810            EditIntegration { guild_id, .. } | DeleteIntegration { guild_id, .. } => {
811                Bucket::GuildsIdIntegrationsId(guild_id)
812            }
813
814            SyncIntegration { guild_id, .. } => Bucket::GuildsIdIntegrationsIdSync(guild_id),
815
816            GetGuildEmbed { guild_id } | EditGuildEmbed { guild_id } => {
817                Bucket::GuildsIdEmbed(guild_id)
818            }
819
820            GetGuildVanityUrl { guild_id } => Bucket::GuildsIdVanityUrl(guild_id),
821
822            GetInvite { .. } | DeleteInvite { .. } => Bucket::InvitesCode,
823
824            GetCurrentUser | EditCurrentUser | GetUser { .. } => Bucket::UsersId,
825
826            GetCurrentUserGuilds => Bucket::UsersMeGuilds,
827
828            LeaveGuild { guild_id } => Bucket::UsersMeGuildsId(guild_id),
829
830            CreatePrivateChannel => Bucket::UsersMeChannels,
831
832            GetVoiceRegions => Bucket::VoiceRegions,
833
834            CreateChannelWebhook { channel_id } | GetChannelWebhooks { channel_id } => {
835                Bucket::ChannelsIdWebhooks(channel_id)
836            }
837
838            GetGuildWebhooks { guild_id } => Bucket::GuildsIdWebhooks(guild_id),
839
840            GetWebhook { webhook_id }
841            | EditWebhook { webhook_id }
842            | DeleteWebhook { webhook_id } => Bucket::WebhooksId(webhook_id),
843
844            GetWebhookWithToken { webhook_id, .. }
845            | EditWebhookWithToken { webhook_id, .. }
846            | DeleteWebhookWithToken { webhook_id, .. }
847            | ExecuteWebhook { webhook_id, .. } => Bucket::WebhooksIdToken(webhook_id),
848
849            GetGateway => Bucket::Gateway,
850            GetBotGateway => Bucket::GatewayBot,
851        }
852    }
853
854    pub(crate) fn url(&self) -> Cow<'a, str> {
855        use self::Route::*;
856
857        match self {
858            GetAuditLogs {
859                guild_id,
860                user_id,
861                action_type,
862                before,
863                limit,
864            } => {
865                let action_type = action_type.map(u8::from);
866                Cow::from(api!("/guilds/{}/audit-logs", guild_id; [
867                    ("user_id", user_id?),
868                    ("action_type", action_type?),
869                    ("before", before?),
870                    ("limit", limit?),
871                ]))
872            }
873
874            GetChannel { channel_id }
875            | EditChannel { channel_id }
876            | DeleteChannel { channel_id } => Cow::from(api!("/channels/{}", channel_id)),
877
878            GetMessages {
879                channel_id,
880                around,
881                limit,
882            } => {
883                let mut s = api!("/channels/{}/messages", channel_id; [
884                    ("limit", limit?),
885                ]);
886                let _ = match around {
887                    Some(AroundMessage::Around(message_id)) => write!(s, "&around={}", message_id),
888                    Some(AroundMessage::Before(message_id)) => write!(s, "&before={}", message_id),
889                    Some(AroundMessage::After(message_id)) => write!(s, "&after={}", message_id),
890                    None => Ok(()),
891                };
892                Cow::from(s)
893            }
894
895            GetMessage {
896                channel_id,
897                message_id,
898            } => Cow::from(api!("/channels/{}/messages/{}", channel_id, message_id)),
899
900            CreateMessage { channel_id } => Cow::from(api!("/channels/{}/messages", channel_id)),
901
902            CreateReaction {
903                channel_id,
904                message_id,
905                emoji,
906            }
907            | DeleteOwnReaction {
908                channel_id,
909                message_id,
910                emoji,
911            } => Cow::from(api!(
912                "/channels/{}/messages/{}/reactions/{}/@me",
913                channel_id,
914                message_id,
915                emoji,
916            )),
917
918            DeleteReaction {
919                channel_id,
920                message_id,
921                emoji,
922                user_id,
923            } => Cow::from(api!(
924                "/channels/{}/messages/{}/reactions/{}/{}",
925                channel_id,
926                message_id,
927                emoji,
928                user_id,
929            )),
930
931            GetReactionUsers {
932                channel_id,
933                message_id,
934                emoji,
935                before,
936                after,
937                limit,
938            } => Cow::from(api!(
939                "/channels/{}/messages/{}/reactions/{}",
940                channel_id,
941                message_id,
942                emoji;
943                [
944                    ("before", before?),
945                    ("after", after?),
946                    ("limit", limit?),
947                ]
948            )),
949
950            DeleteReactions {
951                channel_id,
952                message_id,
953            } => Cow::from(api!(
954                "/channels/{}/messages/{}/reactions",
955                channel_id,
956                message_id,
957            )),
958
959            EditMessage {
960                channel_id,
961                message_id,
962            }
963            | DeleteMessage {
964                channel_id,
965                message_id,
966            } => Cow::from(api!("/channels/{}/messages/{}", channel_id, message_id)),
967
968            DeleteMessagesBulk { channel_id } => {
969                Cow::from(api!("/channels/{}/messages/bulk-delete", channel_id))
970            }
971
972            EditChannelPermission {
973                channel_id,
974                overwrite_id,
975            }
976            | DeleteChannelPermission {
977                channel_id,
978                overwrite_id,
979            } => Cow::from(api!(
980                "/channels/{}/permissions/{}",
981                channel_id,
982                overwrite_id,
983            )),
984
985            GetInvites { channel_id } | CreateInvite { channel_id } => {
986                Cow::from(api!("/channels/{}/invites", channel_id))
987            }
988
989            BroadcastTyping { channel_id } => Cow::from(api!("/channels/{}/typing", channel_id)),
990
991            GetPins { channel_id } => Cow::from(api!("/channels/{}/pins", channel_id)),
992
993            PinMessage {
994                channel_id,
995                message_id,
996            }
997            | UnpinMessage {
998                channel_id,
999                message_id,
1000            } => Cow::from(api!("/channels/{}/pins/{}", channel_id, message_id)),
1001
1002            AddGroupRecipient {
1003                channel_id,
1004                user_id,
1005            }
1006            | RemoveGroupRecipient {
1007                channel_id,
1008                user_id,
1009            } => Cow::from(api!("/channels/{}/recipients/{}", channel_id, user_id)),
1010
1011            GetGuildEmojis { guild_id } | CreateEmoji { guild_id } => {
1012                Cow::from(api!("/guilds/{}/emojis", guild_id))
1013            }
1014
1015            GetEmoji { guild_id, emoji_id }
1016            | EditEmoji { guild_id, emoji_id }
1017            | DeleteEmoji { guild_id, emoji_id } => {
1018                Cow::from(api!("/guilds/{}/emojis/{}", guild_id, emoji_id))
1019            }
1020
1021            CreateGuild => Cow::from(api!("/guilds")),
1022
1023            GetGuild { guild_id } | EditGuild { guild_id } | DeleteGuild { guild_id } => {
1024                Cow::from(api!("/guilds/{}", guild_id))
1025            }
1026
1027            GetChannels { guild_id }
1028            | CreateChannel { guild_id }
1029            | EditChannelPositions { guild_id } => Cow::from(api!("/guilds/{}/channels", guild_id)),
1030
1031            GetMember { guild_id, user_id }
1032            | EditMember { guild_id, user_id }
1033            | KickMember { guild_id, user_id } => {
1034                Cow::from(api!("/guilds/{}/members/{}", guild_id, user_id))
1035            }
1036
1037            GetGuildMembers {
1038                guild_id,
1039                limit,
1040                after,
1041            } => Cow::from(api!("/guilds/{}/members", guild_id; [
1042                ("limit", limit?),
1043                ("after", after?),
1044            ])),
1045
1046            EditNickname { guild_id } => Cow::from(api!("/guilds/{}/members/@me/nick", guild_id)),
1047
1048            AddMemberRole {
1049                guild_id,
1050                user_id,
1051                role_id,
1052            }
1053            | RemoveMemberRole {
1054                guild_id,
1055                user_id,
1056                role_id,
1057            } => Cow::from(api!(
1058                "/guilds/{}/members/{}/roles/{}",
1059                guild_id,
1060                user_id,
1061                role_id,
1062            )),
1063
1064            GetBans { guild_id } => Cow::from(api!("/guilds/{}/bans", guild_id)),
1065
1066            GetBan { guild_id, user_id } | UnbanMember { guild_id, user_id } => {
1067                Cow::from(api!("/guilds/{}/bans/{}", guild_id, user_id))
1068            }
1069
1070            BanMember {
1071                guild_id,
1072                user_id,
1073                delete_message_days,
1074                reason,
1075            } => Cow::from(api!("/guilds/{}/bans/{}", guild_id, user_id; [
1076                ("delete-message-days", delete_message_days?),
1077                ("reason", reason?),
1078            ])),
1079
1080            GetRoles { guild_id } | CreateRole { guild_id } | EditRolePositions { guild_id } => {
1081                Cow::from(api!("/guilds/{}/roles", guild_id))
1082            }
1083
1084            EditRole { guild_id, role_id } | DeleteRole { guild_id, role_id } => {
1085                Cow::from(api!("/guilds/{}/roles/{}", guild_id, role_id))
1086            }
1087
1088            GetGuildPruneCount { guild_id, days } => {
1089                Cow::from(api!("/guilds/{}/prune", guild_id; [
1090                    ("days", days?),
1091                ]))
1092            }
1093
1094            PruneGuildMembers {
1095                guild_id,
1096                days,
1097                compute_prune_count,
1098            } => Cow::from(api!("/guilds/{}/prune", guild_id; [
1099                ("days", days?),
1100                ("compute_prune_count", compute_prune_count?),
1101            ])),
1102
1103            GetGuildRegions { guild_id } => Cow::from(api!("/guilds/{}/regions", guild_id)),
1104
1105            GetGuildInvites { guild_id } => Cow::from(api!("/guilds/{}/invites", guild_id)),
1106
1107            GetGuildIntegrations { guild_id } | CreateIntegration { guild_id } => {
1108                Cow::from(api!("/guilds/{}/integrations", guild_id))
1109            }
1110
1111            EditIntegration {
1112                guild_id,
1113                integration_id,
1114            }
1115            | DeleteIntegration {
1116                guild_id,
1117                integration_id,
1118            } => Cow::from(api!("/guilds/{}/integrations/{}", guild_id, integration_id)),
1119
1120            SyncIntegration {
1121                guild_id,
1122                integration_id,
1123            } => Cow::from(api!(
1124                "/guilds/{}/integrations/{}/sync",
1125                guild_id,
1126                integration_id,
1127            )),
1128
1129            GetGuildEmbed { guild_id } | EditGuildEmbed { guild_id } => {
1130                Cow::from(api!("/guilds/{}/embed", guild_id))
1131            }
1132
1133            GetGuildVanityUrl { guild_id } => Cow::from(api!("/guilds/{}/vanity-url", guild_id)),
1134
1135            GetInvite { code, with_counts } => Cow::from(api!("/invites/{}", code; [
1136                ("with_counts", with_counts?),
1137            ])),
1138
1139            DeleteInvite { code } => Cow::from(api!("/invites/{}", code)),
1140
1141            GetCurrentUser | EditCurrentUser => Cow::from(api!("/users/@me")),
1142
1143            GetCurrentUserGuilds => Cow::from(api!("/users/@me/guilds")),
1144
1145            GetUser { user_id } => Cow::from(api!("/users/{}", user_id)),
1146
1147            LeaveGuild { guild_id } => Cow::from(api!("/user/@me/guilds/{}", guild_id)),
1148
1149            CreatePrivateChannel => Cow::from(api!("/users/@me/channels")),
1150
1151            GetVoiceRegions => Cow::from(api!("/voice/regions")),
1152
1153            CreateChannelWebhook { channel_id } | GetChannelWebhooks { channel_id } => {
1154                Cow::from(api!("/channels/{}/webhooks", channel_id))
1155            }
1156
1157            GetGuildWebhooks { guild_id } => Cow::from(api!("/guilds/{}/webhooks", guild_id)),
1158
1159            GetWebhook { webhook_id }
1160            | EditWebhook { webhook_id }
1161            | DeleteWebhook { webhook_id } => Cow::from(api!("/webhooks/{}", webhook_id)),
1162
1163            GetWebhookWithToken { webhook_id, token }
1164            | EditWebhookWithToken { webhook_id, token }
1165            | DeleteWebhookWithToken { webhook_id, token } => {
1166                Cow::from(api!("/webhooks/{}/{}", webhook_id, token))
1167            }
1168
1169            ExecuteWebhook {
1170                webhook_id,
1171                token,
1172                wait,
1173            } => Cow::from(api!("/webhooks/{}/{}", webhook_id, token; [
1174                ("wait", wait?),
1175            ])),
1176
1177            GetGateway => Cow::from(api!("/gateway")),
1178            GetBotGateway => Cow::from(api!("/gateway/bot")),
1179        }
1180    }
1181}
1182
1183/// Methods implementing `Copy`, with mappings to corresponding reqwest methods.
1184#[remain::sorted]
1185#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1186pub enum Method {
1187    Delete,
1188    Get,
1189    Patch,
1190    Post,
1191    Put,
1192}
1193
1194impl From<Method> for HttpMethod {
1195    fn from(method: Method) -> Self {
1196        match method {
1197            Method::Delete => HttpMethod::DELETE,
1198            Method::Get => HttpMethod::GET,
1199            Method::Patch => HttpMethod::PATCH,
1200            Method::Post => HttpMethod::POST,
1201            Method::Put => HttpMethod::PUT,
1202        }
1203    }
1204}
1205
1206#[derive(Clone, Copy, Debug)]
1207pub enum AroundMessage {
1208    Around(MessageId),
1209    Before(MessageId),
1210    After(MessageId),
1211}