From d92b9ebf0a8d75e46ba01d4267610803de430bc4 Mon Sep 17 00:00:00 2001 From: Gnome! Date: Sun, 3 Dec 2023 12:43:27 +0000 Subject: [PATCH] Remove temporary `Vec` usage in the `http` module (#2624, #2646) This avoids having to allocate to store fixed length (replaced with normal array) or fixed capacity (replaced with `ArrayVec`) collections as vectors for the purposes of putting them through the `Request` plumbing. Slight behavioral change - before, setting `params` to `Some(vec![])` would still append a question mark to the end of the url. Now, we check if the params array `is_empty` instead of `is_some`, so the question mark won't be appended if the params list is empty. Co-authored-by: Michael Krasnitski <42564254+mkrasnitski@users.noreply.github.com> --- src/http/client.rs | 415 +++++++++++++++++++++------------------ src/http/ratelimiting.rs | 13 +- src/http/request.rs | 37 ++-- 3 files changed, 255 insertions(+), 210 deletions(-) diff --git a/src/http/client.rs b/src/http/client.rs index aabe40dde4a..439465d09e7 100644 --- a/src/http/client.rs +++ b/src/http/client.rs @@ -5,6 +5,7 @@ use std::num::NonZeroU64; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; +use arrayvec::ArrayVec; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use reqwest::header::{HeaderMap as Headers, HeaderValue}; #[cfg(feature = "utils")] @@ -232,7 +233,7 @@ impl Http { guild_id, user_id, }, - params: None, + params: [].into(), }) .await?; @@ -265,7 +266,7 @@ impl Http { role_id, user_id, }, - params: None, + params: [].into(), }) .await } @@ -295,7 +296,7 @@ impl Http { guild_id, user_id, }, - params: Some(vec![("delete_message_days", delete_message_days.to_string())]), + params: [("delete_message_days", delete_message_days.to_string())].into(), }) .await } @@ -316,7 +317,7 @@ impl Http { route: Route::ChannelTyping { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -345,7 +346,7 @@ impl Http { route: Route::GuildChannels { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -362,7 +363,7 @@ impl Http { headers: audit_log_reason.map(reason_into_header), method: LightMethod::Post, route: Route::StageInstances, - params: None, + params: [].into(), }) .await } @@ -386,7 +387,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }) .await } @@ -408,7 +409,7 @@ impl Http { route: Route::ChannelThreads { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -443,7 +444,7 @@ impl Http { route: Route::ChannelForumPosts { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -469,7 +470,7 @@ impl Http { route: Route::GuildEmojis { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -492,7 +493,7 @@ impl Http { application_id: self.try_application_id()?, token: interaction_token, }, - params: None, + params: [].into(), }; if files.is_empty() { @@ -527,7 +528,7 @@ impl Http { route: Route::Commands { application_id: self.try_application_id()?, }, - params: None, + params: [].into(), }) .await } @@ -545,7 +546,7 @@ impl Http { route: Route::Commands { application_id: self.try_application_id()?, }, - params: None, + params: [].into(), }) .await } @@ -565,7 +566,7 @@ impl Http { application_id: self.try_application_id()?, guild_id, }, - params: None, + params: [].into(), }) .await } @@ -610,7 +611,7 @@ impl Http { headers: None, method: LightMethod::Post, route: Route::Guilds, - params: None, + params: [].into(), }) .await } @@ -636,7 +637,7 @@ impl Http { application_id: self.try_application_id()?, guild_id, }, - params: None, + params: [].into(), }) .await } @@ -665,7 +666,7 @@ impl Http { guild_id, integration_id, }, - params: None, + params: [].into(), }) .await } @@ -692,7 +693,7 @@ impl Http { interaction_id, token: interaction_token, }, - params: None, + params: [].into(), }; if files.is_empty() { @@ -734,7 +735,7 @@ impl Http { route: Route::ChannelInvites { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -758,7 +759,7 @@ impl Http { channel_id, target_id, }, - params: None, + params: [].into(), }) .await } @@ -773,7 +774,7 @@ impl Http { headers: None, method: LightMethod::Post, route: Route::UserMeDmChannels, - params: None, + params: [].into(), }) .await } @@ -795,7 +796,7 @@ impl Http { message_id, reaction: &reaction_type.as_data(), }, - params: None, + params: [].into(), }) .await } @@ -816,7 +817,7 @@ impl Http { route: Route::GuildRoles { guild_id, }, - params: None, + params: [].into(), }) .await?; @@ -849,7 +850,7 @@ impl Http { route: Route::GuildScheduledEvents { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -878,7 +879,7 @@ impl Http { route: Route::GuildStickers { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -955,7 +956,7 @@ impl Http { route: Route::ChannelWebhooks { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -974,7 +975,7 @@ impl Http { route: Route::Channel { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -993,7 +994,7 @@ impl Http { route: Route::StageInstance { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -1016,7 +1017,7 @@ impl Http { guild_id, emoji_id, }, - params: None, + params: [].into(), }) .await } @@ -1037,7 +1038,7 @@ impl Http { token: interaction_token, message_id, }, - params: None, + params: [].into(), }) .await } @@ -1053,7 +1054,7 @@ impl Http { application_id: self.try_application_id()?, command_id, }, - params: None, + params: [].into(), }) .await } @@ -1068,7 +1069,7 @@ impl Http { route: Route::Guild { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -1089,7 +1090,7 @@ impl Http { guild_id, command_id, }, - params: None, + params: [].into(), }) .await } @@ -1110,7 +1111,7 @@ impl Http { guild_id, integration_id, }, - params: None, + params: [].into(), }) .await } @@ -1129,7 +1130,7 @@ impl Http { route: Route::Invite { code, }, - params: None, + params: [].into(), }) .await } @@ -1150,7 +1151,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }) .await } @@ -1170,7 +1171,7 @@ impl Http { route: Route::ChannelMessagesBulkDelete { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -1207,7 +1208,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }) .await } @@ -1229,7 +1230,7 @@ impl Http { message_id, reaction: &reaction_type.as_data(), }, - params: None, + params: [].into(), }) .await } @@ -1248,7 +1249,7 @@ impl Http { application_id: self.try_application_id()?, token: interaction_token, }, - params: None, + params: [].into(), }) .await } @@ -1269,7 +1270,7 @@ impl Http { channel_id, target_id, }, - params: None, + params: [].into(), }) .await } @@ -1293,7 +1294,7 @@ impl Http { user_id, reaction: &reaction_type.as_data(), }, - params: None, + params: [].into(), }) .await } @@ -1315,7 +1316,7 @@ impl Http { message_id, reaction: &reaction_type.as_data(), }, - params: None, + params: [].into(), }) .await } @@ -1336,7 +1337,7 @@ impl Http { guild_id, role_id, }, - params: None, + params: [].into(), }) .await } @@ -1361,7 +1362,7 @@ impl Http { guild_id, event_id, }, - params: None, + params: [].into(), }) .await } @@ -1384,7 +1385,7 @@ impl Http { guild_id, sticker_id, }, - params: None, + params: [].into(), }) .await } @@ -1438,7 +1439,7 @@ impl Http { route: Route::Webhook { webhook_id, }, - params: None, + params: [].into(), }) .await } @@ -1479,7 +1480,7 @@ impl Http { webhook_id, token, }, - params: None, + params: [].into(), }) .await } @@ -1501,7 +1502,7 @@ impl Http { route: Route::Channel { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -1521,7 +1522,7 @@ impl Http { route: Route::StageInstance { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -1547,7 +1548,7 @@ impl Http { guild_id, emoji_id, }, - params: None, + params: [].into(), }) .await } @@ -1574,7 +1575,7 @@ impl Http { token: interaction_token, message_id, }, - params: None, + params: [].into(), }; if new_attachments.is_empty() { @@ -1610,7 +1611,7 @@ impl Http { token: interaction_token, message_id, }, - params: None, + params: [].into(), }) .await } @@ -1636,7 +1637,7 @@ impl Http { application_id: self.try_application_id()?, command_id, }, - params: None, + params: [].into(), }) .await } @@ -1658,7 +1659,7 @@ impl Http { route: Route::Guild { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -1686,7 +1687,7 @@ impl Http { guild_id, command_id, }, - params: None, + params: [].into(), }) .await } @@ -1714,7 +1715,7 @@ impl Http { guild_id, command_id, }, - params: None, + params: [].into(), }) .await } @@ -1735,7 +1736,7 @@ impl Http { route: Route::GuildChannels { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -1762,7 +1763,7 @@ impl Http { route: Route::GuildMfa { guild_id, }, - params: None, + params: [].into(), }) .await .map(|mfa: GuildMfaLevel| mfa.level) @@ -1785,7 +1786,7 @@ impl Http { route: Route::GuildWidget { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -1807,7 +1808,7 @@ impl Http { route: Route::GuildWelcomeScreen { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -1832,7 +1833,7 @@ impl Http { guild_id, user_id, }, - params: None, + params: [].into(), }) .await?; @@ -1862,7 +1863,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }; if new_attachments.is_empty() { @@ -1895,7 +1896,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }) .await } @@ -1917,7 +1918,7 @@ impl Http { route: Route::GuildMemberMe { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -1942,7 +1943,7 @@ impl Http { route: Route::GuildMemberMe { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -1964,7 +1965,7 @@ impl Http { route: Route::ChannelFollowNews { channel_id: news_channel_id, }, - params: None, + params: [].into(), }) .await } @@ -1983,7 +1984,7 @@ impl Http { application_id: self.try_application_id()?, token: interaction_token, }, - params: None, + params: [].into(), }) .await } @@ -2008,7 +2009,7 @@ impl Http { application_id: self.try_application_id()?, token: interaction_token, }, - params: None, + params: [].into(), }; if new_attachments.is_empty() { @@ -2034,7 +2035,7 @@ impl Http { headers: None, method: LightMethod::Patch, route: Route::UserMe, - params: None, + params: [].into(), }) .await } @@ -2057,7 +2058,7 @@ impl Http { guild_id, role_id, }, - params: None, + params: [].into(), }) .await?; @@ -2091,7 +2092,7 @@ impl Http { route: Route::GuildRoles { guild_id, }, - params: None, + params: [].into(), }) .await?; @@ -2128,7 +2129,7 @@ impl Http { guild_id, event_id, }, - params: None, + params: [].into(), }) .await } @@ -2155,7 +2156,7 @@ impl Http { guild_id, sticker_id, }, - params: None, + params: [].into(), }) .await?; @@ -2181,7 +2182,7 @@ impl Http { route: Route::Channel { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -2231,7 +2232,7 @@ impl Http { guild_id, user_id, }, - params: None, + params: [].into(), }) .await } @@ -2282,7 +2283,7 @@ impl Http { route: Route::GuildVoiceStateMe { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -2333,7 +2334,7 @@ impl Http { route: Route::Webhook { webhook_id, }, - params: None, + params: [].into(), }) .await } @@ -2381,7 +2382,7 @@ impl Http { webhook_id, token, }, - params: None, + params: [].into(), }) .await } @@ -2445,7 +2446,9 @@ impl Http { files: Vec, map: &impl serde::Serialize, ) -> Result> { - let mut params = vec![("wait", wait.to_string())]; + let mut params = ArrayVec::<_, 2>::new(); + + params.push(("wait", wait.to_string())); if let Some(thread_id) = thread_id { params.push(("thread_id", thread_id.to_string())); } @@ -2459,7 +2462,7 @@ impl Http { webhook_id, token, }, - params: Some(params), + params, }; if files.is_empty() { @@ -2489,6 +2492,11 @@ impl Http { token: &str, message_id: MessageId, ) -> Result { + let mut params = ArrayVec::<_, 1>::new(); + if let Some(thread_id) = thread_id { + params.push(("thread_id", thread_id.to_string())); + } + self.fire(Request { body: None, multipart: None, @@ -2499,7 +2507,7 @@ impl Http { token, message_id, }, - params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]), + params, }) .await } @@ -2514,6 +2522,11 @@ impl Http { map: &impl serde::Serialize, new_attachments: Vec, ) -> Result { + let mut params = ArrayVec::<_, 1>::new(); + if let Some(thread_id) = thread_id { + params.push(("thread_id", thread_id.to_string())); + } + let mut request = Request { body: None, multipart: None, @@ -2524,7 +2537,7 @@ impl Http { token, message_id, }, - params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]), + params, }; if new_attachments.is_empty() { @@ -2548,6 +2561,11 @@ impl Http { token: &str, message_id: MessageId, ) -> Result<()> { + let mut params = ArrayVec::<_, 1>::new(); + if let Some(thread_id) = thread_id { + params.push(("thread_id", thread_id.to_string())); + } + self.wind(204, Request { body: None, multipart: None, @@ -2558,7 +2576,7 @@ impl Http { token, message_id, }, - params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]), + params, }) .await } @@ -2580,7 +2598,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::StatusMaintenancesActive, - params: None, + params: [].into(), }) .await?; @@ -2603,7 +2621,7 @@ impl Http { target: Option, limit: Option, ) -> Result> { - let mut params = vec![]; + let mut params = ArrayVec::<_, 2>::new(); if let Some(limit) = limit { params.push(("limit", limit.to_string())); @@ -2624,7 +2642,7 @@ impl Http { route: Route::GuildBans { guild_id, }, - params: Some(params), + params, }) .await } @@ -2638,7 +2656,7 @@ impl Http { before: Option, limit: Option, ) -> Result { - let mut params = vec![]; + let mut params = ArrayVec::<_, 4>::new(); if let Some(action_type) = action_type { params.push(("action_type", action_type.num().to_string())); } @@ -2660,7 +2678,7 @@ impl Http { route: Route::GuildAuditLogs { guild_id, }, - params: Some(params), + params, }) .await } @@ -2677,7 +2695,7 @@ impl Http { route: Route::GuildAutomodRules { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -2695,7 +2713,7 @@ impl Http { guild_id, rule_id, }, - params: None, + params: [].into(), }) .await } @@ -2719,7 +2737,7 @@ impl Http { route: Route::GuildAutomodRules { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -2745,7 +2763,7 @@ impl Http { guild_id, rule_id, }, - params: None, + params: [].into(), }) .await } @@ -2768,7 +2786,7 @@ impl Http { guild_id, rule_id, }, - params: None, + params: [].into(), }) .await } @@ -2781,7 +2799,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::GatewayBot, - params: None, + params: [].into(), }) .await } @@ -2796,7 +2814,7 @@ impl Http { route: Route::ChannelInvites { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -2814,7 +2832,7 @@ impl Http { route: Route::ChannelThreadMembers { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -2829,7 +2847,7 @@ impl Http { route: Route::GuildThreadsActive { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -2841,7 +2859,7 @@ impl Http { before: Option, limit: Option, ) -> Result { - let mut params = vec![]; + let mut params = ArrayVec::<_, 2>::new(); if let Some(before) = before { params.push(("before", before.to_string())); } @@ -2857,7 +2875,7 @@ impl Http { route: Route::ChannelArchivedPublicThreads { channel_id, }, - params: Some(params), + params, }) .await } @@ -2869,7 +2887,7 @@ impl Http { before: Option, limit: Option, ) -> Result { - let mut params = vec![]; + let mut params = ArrayVec::<_, 2>::new(); if let Some(before) = before { params.push(("before", before.to_string())); } @@ -2885,7 +2903,7 @@ impl Http { route: Route::ChannelArchivedPrivateThreads { channel_id, }, - params: Some(params), + params, }) .await } @@ -2897,7 +2915,7 @@ impl Http { before: Option, limit: Option, ) -> Result { - let mut params = vec![]; + let mut params = ArrayVec::<_, 2>::new(); if let Some(before) = before { params.push(("before", before.to_string())); } @@ -2913,7 +2931,7 @@ impl Http { route: Route::ChannelJoinedPrivateThreads { channel_id, }, - params: Some(params), + params, }) .await } @@ -2928,7 +2946,7 @@ impl Http { route: Route::ChannelThreadMemberMe { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -2943,7 +2961,7 @@ impl Http { route: Route::ChannelThreadMemberMe { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -2963,7 +2981,7 @@ impl Http { channel_id, user_id, }, - params: None, + params: [].into(), }) .await } @@ -2983,7 +3001,7 @@ impl Http { channel_id, user_id, }, - params: None, + params: [].into(), }) .await } @@ -3017,7 +3035,7 @@ impl Http { route: Route::ChannelWebhooks { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -3032,7 +3050,7 @@ impl Http { route: Route::Channel { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -3047,7 +3065,7 @@ impl Http { route: Route::GuildChannels { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3062,7 +3080,7 @@ impl Http { route: Route::StageInstance { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -3077,7 +3095,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::Oauth2ApplicationCurrent, - params: None, + params: [].into(), }) .await } @@ -3090,7 +3108,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::UserMe, - params: None, + params: [].into(), }) .await } @@ -3105,7 +3123,7 @@ impl Http { route: Route::GuildEmojis { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3121,7 +3139,7 @@ impl Http { guild_id, emoji_id, }, - params: None, + params: [].into(), }) .await } @@ -3185,7 +3203,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::Gateway, - params: None, + params: [].into(), }) .await } @@ -3200,7 +3218,7 @@ impl Http { route: Route::Commands { application_id: self.try_application_id()?, }, - params: None, + params: [].into(), }) .await } @@ -3215,7 +3233,7 @@ impl Http { route: Route::Commands { application_id: self.try_application_id()?, }, - params: Some(vec![("with_localizations", true.to_string())]), + params: [("with_localizations", String::from("true"))].into(), }) .await } @@ -3231,7 +3249,7 @@ impl Http { application_id: self.try_application_id()?, command_id, }, - params: None, + params: [].into(), }) .await } @@ -3246,7 +3264,7 @@ impl Http { route: Route::Guild { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3261,7 +3279,7 @@ impl Http { route: Route::Guild { guild_id, }, - params: Some(vec![("with_counts", true.to_string())]), + params: [("with_counts", String::from("true"))].into(), }) .await } @@ -3277,7 +3295,7 @@ impl Http { application_id: self.try_application_id()?, guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3297,7 +3315,7 @@ impl Http { application_id: self.try_application_id()?, guild_id, }, - params: Some(vec![("with_localizations", true.to_string())]), + params: [("with_localizations", String::from("true"))].into(), }) .await } @@ -3318,7 +3336,7 @@ impl Http { guild_id, command_id, }, - params: None, + params: [].into(), }) .await } @@ -3337,7 +3355,7 @@ impl Http { application_id: self.try_application_id()?, guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3358,7 +3376,7 @@ impl Http { guild_id, command_id, }, - params: None, + params: [].into(), }) .await } @@ -3375,7 +3393,7 @@ impl Http { route: Route::GuildWidget { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3390,7 +3408,7 @@ impl Http { route: Route::GuildPreview { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3405,7 +3423,7 @@ impl Http { route: Route::GuildWelcomeScreen { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3420,7 +3438,7 @@ impl Http { route: Route::GuildIntegrations { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3435,7 +3453,7 @@ impl Http { route: Route::GuildInvites { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3447,7 +3465,7 @@ impl Http { code: String, } - self.fire::(Request { + self.fire(Request { body: None, multipart: None, headers: None, @@ -3455,10 +3473,10 @@ impl Http { route: Route::GuildVanityUrl { guild_id, }, - params: None, + params: [].into(), }) .await - .map(|x| x.code) + .map(|x: GuildVanityUrl| x.code) } /// Gets the members of a guild. Optionally pass a `limit` and the Id of the user to offset the @@ -3475,8 +3493,8 @@ impl Http { } } - let mut params = - vec![("limit", limit.unwrap_or(constants::MEMBER_FETCH_LIMIT).to_string())]; + let mut params = ArrayVec::<_, 2>::new(); + params.push(("limit", limit.unwrap_or(constants::MEMBER_FETCH_LIMIT).to_string())); if let Some(after) = after { params.push(("after", after.to_string())); } @@ -3490,7 +3508,7 @@ impl Http { route: Route::GuildMembers { guild_id, }, - params: Some(params), + params, }) .await?; @@ -3515,7 +3533,7 @@ impl Http { route: Route::GuildPrune { guild_id, }, - params: Some(vec![("days", days.to_string())]), + params: [("days", days.to_string())].into(), }) .await } @@ -3531,7 +3549,7 @@ impl Http { route: Route::GuildRegions { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3547,7 +3565,7 @@ impl Http { route: Route::GuildRoles { guild_id, }, - params: None, + params: [].into(), }) .await?; @@ -3582,7 +3600,7 @@ impl Http { guild_id, event_id, }, - params: Some(vec![("with_user_count", with_user_count.to_string())]), + params: [("with_user_count", with_user_count.to_string())].into(), }) .await } @@ -3605,7 +3623,7 @@ impl Http { route: Route::GuildScheduledEvents { guild_id, }, - params: Some(vec![("with_user_count", with_user_count.to_string())]), + params: [("with_user_count", with_user_count.to_string())].into(), }) .await } @@ -3634,7 +3652,7 @@ impl Http { target: Option, with_member: Option, ) -> Result> { - let mut params = vec![]; + let mut params = ArrayVec::<_, 3>::new(); if let Some(limit) = limit { params.push(("limit", limit.to_string())); } @@ -3657,7 +3675,7 @@ impl Http { guild_id, event_id, }, - params: Some(params), + params, }) .await } @@ -3673,7 +3691,7 @@ impl Http { route: Route::GuildStickers { guild_id, }, - params: None, + params: [].into(), }) .await?; @@ -3704,7 +3722,7 @@ impl Http { guild_id, sticker_id, }, - params: None, + params: [].into(), }) .await?; @@ -3744,7 +3762,7 @@ impl Http { route: Route::GuildWebhooks { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -3780,7 +3798,7 @@ impl Http { target: Option, limit: Option, ) -> Result> { - let mut params = vec![]; + let mut params = ArrayVec::<_, 2>::new(); if let Some(limit) = limit { params.push(("limit", limit.to_string())); } @@ -3797,7 +3815,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::UserMeGuilds, - params: Some(params), + params, }) .await } @@ -3841,7 +3859,7 @@ impl Http { route: Route::UserMeGuildMember { guild_id, }, - params: None, + params: [].into(), }) .await?; @@ -3873,10 +3891,9 @@ impl Http { #[cfg(feature = "utils")] let code = crate::utils::parse_invite(code); - let mut params = vec![ - ("member_counts", member_counts.to_string()), - ("expiration", expiration.to_string()), - ]; + let mut params = ArrayVec::<_, 3>::new(); + params.push(("member_counts", member_counts.to_string())); + params.push(("expiration", expiration.to_string())); if let Some(event_id) = event_id { params.push(("event_id", event_id.to_string())); } @@ -3889,7 +3906,7 @@ impl Http { route: Route::Invite { code, }, - params: Some(params), + params, }) .await } @@ -3906,7 +3923,7 @@ impl Http { guild_id, user_id, }, - params: None, + params: [].into(), }) .await?; @@ -3932,7 +3949,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }) .await } @@ -3944,7 +3961,7 @@ impl Http { target: Option, limit: Option, ) -> Result> { - let mut params = vec![]; + let mut params = ArrayVec::<_, 2>::new(); if let Some(limit) = limit { params.push(("limit", limit.to_string())); } @@ -3964,7 +3981,7 @@ impl Http { route: Route::ChannelMessages { channel_id, }, - params: Some(params), + params, }) .await } @@ -3976,16 +3993,16 @@ impl Http { sticker_packs: Vec, } - self.fire::(Request { + self.fire(Request { body: None, multipart: None, headers: None, method: LightMethod::Get, route: Route::StickerPacks, - params: None, + params: [].into(), }) .await - .map(|s| s.sticker_packs) + .map(|s: StickerPacks| s.sticker_packs) } /// Gets all pins of a channel. @@ -3998,7 +4015,7 @@ impl Http { route: Route::ChannelPins { channel_id, }, - params: None, + params: [].into(), }) .await } @@ -4012,7 +4029,8 @@ impl Http { limit: u8, after: Option, ) -> Result> { - let mut params = vec![("limit", limit.to_string())]; + let mut params = ArrayVec::<_, 2>::new(); + params.push(("limit", limit.to_string())); if let Some(after) = after { params.push(("after", after.to_string())); } @@ -4026,7 +4044,7 @@ impl Http { message_id, reaction: &reaction_type.as_data(), }, - params: Some(params), + params, }) .await } @@ -4056,7 +4074,7 @@ impl Http { route: Route::Sticker { sticker_id, }, - params: None, + params: [].into(), }) .await } @@ -4078,7 +4096,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::StatusIncidentsUnresolved, - params: None, + params: [].into(), }) .await?; @@ -4102,7 +4120,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::StatusMaintenancesUpcoming, - params: None, + params: [].into(), }) .await?; @@ -4119,7 +4137,7 @@ impl Http { route: Route::User { user_id, }, - params: None, + params: [].into(), }) .await } @@ -4136,7 +4154,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::UserMeConnections, - params: None, + params: [].into(), }) .await } @@ -4149,7 +4167,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::UserMeDmChannels, - params: None, + params: [].into(), }) .await } @@ -4162,7 +4180,7 @@ impl Http { headers: None, method: LightMethod::Get, route: Route::VoiceRegions, - params: None, + params: [].into(), }) .await } @@ -4196,7 +4214,7 @@ impl Http { route: Route::Webhook { webhook_id, }, - params: None, + params: [].into(), }) .await } @@ -4236,7 +4254,7 @@ impl Http { webhook_id, token, }, - params: None, + params: [].into(), }) .await } @@ -4273,7 +4291,7 @@ impl Http { webhook_id, token, }, - params: None, + params: [].into(), }) .await } @@ -4294,7 +4312,7 @@ impl Http { guild_id, user_id, }, - params: None, + params: [].into(), }) .await } @@ -4309,7 +4327,7 @@ impl Http { route: Route::UserMeGuild { guild_id, }, - params: None, + params: [].into(), }) .await } @@ -4333,7 +4351,7 @@ impl Http { route: Route::ChannelMessages { channel_id, }, - params: None, + params: [].into(), }; if files.is_empty() { @@ -4365,7 +4383,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }) .await } @@ -4386,7 +4404,7 @@ impl Http { guild_id, user_id, }, - params: None, + params: [].into(), }) .await } @@ -4413,7 +4431,7 @@ impl Http { user_id, role_id, }, - params: None, + params: [].into(), }) .await } @@ -4435,10 +4453,11 @@ impl Http { route: Route::GuildMembersSearch { guild_id, }, - params: Some(vec![ + params: [ ("query", query.to_string()), ("limit", limit.unwrap_or(constants::MEMBER_FETCH_LIMIT).to_string()), - ]), + ] + .into(), }) .await?; @@ -4468,7 +4487,7 @@ impl Http { route: Route::GuildPrune { guild_id, }, - params: Some(vec![("days", days.to_string())]), + params: [("days", days.to_string())].into(), }) .await } @@ -4488,7 +4507,7 @@ impl Http { guild_id, integration_id, }, - params: None, + params: [].into(), }) .await } @@ -4549,7 +4568,7 @@ impl Http { channel_id, message_id, }, - params: None, + params: [].into(), }) .await } @@ -4579,9 +4598,9 @@ impl Http { /// let channel_id = ChannelId::new(381880193700069377); /// let route = Route::ChannelMessages { channel_id }; /// - /// let mut request = Request::new(route, LightMethod::Post).body(Some(bytes)); + /// let mut request = Request::new(route, LightMethod::Post, []).body(Some(bytes)); /// - /// let message = http.fire::(request).await?; + /// let message: Message = http.fire(request).await?; /// /// println!("Message content: {}", message.content); /// # Ok(()) @@ -4591,7 +4610,10 @@ impl Http { /// # Errors /// /// If there is an error, it will be either [`Error::Http`] or [`Error::Json`]. - pub async fn fire(&self, req: Request<'_>) -> Result { + pub async fn fire( + &self, + req: Request<'_, MAX_PARAMS>, + ) -> Result { let response = self.request(req).await?; decode_resp(response).await } @@ -4619,7 +4641,7 @@ impl Http { /// let channel_id = ChannelId::new(381880193700069377); /// let route = Route::ChannelMessages { channel_id }; /// - /// let mut request = Request::new(route, LightMethod::Post).body(Some(bytes)); + /// let mut request = Request::new(route, LightMethod::Post, []).body(Some(bytes)); /// /// let response = http.request(request).await?; /// @@ -4628,7 +4650,10 @@ impl Http { /// # } /// ``` #[instrument] - pub async fn request(&self, req: Request<'_>) -> Result { + pub async fn request( + &self, + req: Request<'_, MAX_PARAMS>, + ) -> Result { let method = req.method.reqwest_method(); let response = if let Some(ratelimiter) = &self.ratelimiter { ratelimiter.perform(req).await? @@ -4651,7 +4676,11 @@ impl Http { /// /// This is a function that performs a light amount of work and returns an empty tuple, so it's /// called "self.wind" to denote that it's lightweight. - pub(super) async fn wind(&self, expected: u16, req: Request<'_>) -> Result<()> { + pub(super) async fn wind( + &self, + expected: u16, + req: Request<'_, MAX_PARAMS>, + ) -> Result<()> { let method = req.method.reqwest_method(); let response = self.request(req).await?; diff --git a/src/http/ratelimiting.rs b/src/http/ratelimiting.rs index cb6904394c5..8fa7928027e 100644 --- a/src/http/ratelimiting.rs +++ b/src/http/ratelimiting.rs @@ -179,7 +179,10 @@ impl Ratelimiter { /// /// Only error kind that may be returned is [`Error::Http`]. #[instrument] - pub async fn perform(&self, req: Request<'_>) -> Result { + pub async fn perform( + &self, + req: Request<'_, MAX_PARAMS>, + ) -> Result { loop { // This will block if another thread hit the global ratelimit. drop(self.global.lock().await); @@ -278,9 +281,9 @@ pub struct Ratelimit { impl Ratelimit { #[instrument(skip(ratelimit_callback))] - pub async fn pre_hook( + pub async fn pre_hook( &mut self, - req: &Request<'_>, + req: &Request<'_, MAX_PARAMS>, ratelimit_callback: &(dyn Fn(RatelimitInfo) + Send + Sync), ) { if self.limit() == 0 { @@ -324,10 +327,10 @@ impl Ratelimit { } #[instrument(skip(ratelimit_callback))] - pub async fn post_hook( + pub async fn post_hook( &mut self, response: &Response, - req: &Request<'_>, + req: &Request<'_, MAX_PARAMS>, ratelimit_callback: &(dyn Fn(RatelimitInfo) + Send + Sync), absolute_ratelimits: bool, ) -> Result { diff --git a/src/http/request.rs b/src/http/request.rs index 0419116fb6b..80235c37928 100644 --- a/src/http/request.rs +++ b/src/http/request.rs @@ -1,5 +1,6 @@ use std::fmt::Write; +use arrayvec::ArrayVec; use reqwest::header::{ HeaderMap as Headers, HeaderValue, @@ -18,28 +19,32 @@ use crate::constants; use crate::internal::prelude::*; #[deprecated = "use Request directly now"] -pub type RequestBuilder<'a> = Request<'a>; +pub type RequestBuilder<'a, const MAX_PARAMS: usize> = Request<'a, MAX_PARAMS>; #[derive(Clone, Debug)] #[must_use] -pub struct Request<'a> { +pub struct Request<'a, const MAX_PARAMS: usize> { pub(super) body: Option>, pub(super) multipart: Option, pub(super) headers: Option, pub(super) method: LightMethod, pub(super) route: Route<'a>, - pub(super) params: Option>, + pub(super) params: ArrayVec<(&'static str, String), MAX_PARAMS>, } -impl<'a> Request<'a> { - pub const fn new(route: Route<'a>, method: LightMethod) -> Self { +impl<'a, const MAX_PARAMS: usize> Request<'a, MAX_PARAMS> { + pub fn new( + route: Route<'a>, + method: LightMethod, + params: [(&'static str, String); MAX_PARAMS], + ) -> Self { Self { body: None, multipart: None, headers: None, method, route, - params: None, + params: params.into(), } } @@ -58,8 +63,8 @@ impl<'a> Request<'a> { self } - pub fn params(mut self, params: Option>) -> Self { - self.params = params; + pub fn params(mut self, params: [(&'static str, String); MAX_PARAMS]) -> Self { + self.params = params.into(); self } @@ -77,9 +82,9 @@ impl<'a> Request<'a> { path = path.replace("https://discord.com", proxy.trim_end_matches('/')); } - if let Some(params) = self.params { + if !self.params.is_empty() { path += "?"; - for (param, value) in params { + for (param, value) in self.params { write!(path, "&{param}={value}").unwrap(); } } @@ -138,11 +143,19 @@ impl<'a> Request<'a> { #[must_use] pub fn params_ref(&self) -> Option<&[(&'static str, String)]> { - self.params.as_deref() + if self.params.is_empty() { + None + } else { + Some(&self.params) + } } #[must_use] pub fn params_mut(&mut self) -> Option<&mut [(&'static str, String)]> { - self.params.as_deref_mut() + if self.params.is_empty() { + None + } else { + Some(&mut self.params) + } } }