Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 2 additions & 29 deletions src/builder/create_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ pub struct CreateMessage<'a> {
enforce_nonce: bool,
#[serde(skip_serializing_if = "Option::is_none")]
poll: Option<CreatePoll<'a, Ready>>,

// The following fields are handled separately.
#[serde(skip)]
reactions: Cow<'a, [ReactionType]>,
}

impl<'a> CreateMessage<'a> {
Expand Down Expand Up @@ -140,12 +136,6 @@ impl<'a> CreateMessage<'a> {
self
}

/// Adds a list of reactions to create after the message's sent.
pub fn reactions(mut self, reactions: impl Into<Cow<'a, [ReactionType]>>) -> Self {
self.reactions = reactions.into();
self
}

/// Appends a file to the message.
///
/// **Note**: Requires the [Attach Files] permission.
Expand Down Expand Up @@ -287,31 +277,14 @@ impl<'a> CreateMessage<'a> {
/// [Send Messages]: Permissions::SEND_MESSAGES
/// [Attach Files]: Permissions::ATTACH_FILES
#[cfg(feature = "http")]
pub async fn execute(
mut self,
http: &Http,
channel_id: GenericChannelId,
guild_id: Option<GuildId>,
) -> Result<Message> {
pub async fn execute(mut self, http: &Http, channel_id: GenericChannelId) -> Result<Message> {
self.check_length()?;

let files = self.attachments.new_attachments();
if self.allowed_mentions.is_none() {
self.allowed_mentions.clone_from(&http.default_allowed_mentions);
}

let mut message = http.send_message(channel_id, files, &self).await?;

for reaction in self.reactions.iter() {
http.create_reaction(channel_id, message.id, reaction).await?;
}

// HTTP sent Messages don't have guild_id set, so we fill it in ourselves by best effort
if message.guild_id.is_none() {
// If we were called from GuildChannel, we can fill in the GuildId ourselves.
message.guild_id = guild_id;
}

Ok(message)
http.send_message(channel_id, files, &self).await
}
}
2 changes: 1 addition & 1 deletion src/http/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4381,7 +4381,7 @@ impl Http {
pub async fn request(&self, req: Request<'_>) -> Result<ReqwestResponse> {
let method = req.method.reqwest_method();
let response = if let Some(ratelimiter) = &self.ratelimiter {
ratelimiter.perform(req).await?
ratelimiter.perform(&req).await?
} else {
let request = req
.build(
Expand Down
3 changes: 2 additions & 1 deletion src/http/multipart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ impl Multipart<'_> {
},
MultipartUpload::Attachments(attachment_files) => {
for (idx, file) in attachment_files.into_iter().enumerate() {
multipart = multipart.part(format!("files[{idx}]"), file.into_part().await?);
let part = file.into_part().await?;
multipart = multipart.part(format!("files[{idx}]"), part);
}
},
}
Expand Down
6 changes: 3 additions & 3 deletions src/http/ratelimiting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl Ratelimiter {
///
/// Only error kind that may be returned is [`Error::Http`].
#[cfg_attr(feature = "tracing_instrument", instrument)]
pub async fn perform(&self, req: Request<'_>) -> Result<Response> {
pub async fn perform(&self, req: &Request<'_>) -> Result<Response> {
loop {
// This will block if another thread hit the global ratelimit.
drop(self.global.lock().await);
Expand All @@ -185,7 +185,7 @@ impl Ratelimiter {
let ratelimiting_bucket = req.route.ratelimiting_bucket();
let delay_time = {
let mut bucket = self.routes.entry(ratelimiting_bucket).or_default();
bucket.pre_hook(&req, &*self.ratelimit_callback.read())
bucket.pre_hook(req, &*self.ratelimit_callback.read())
};

if let Some(delay_time) = delay_time {
Expand Down Expand Up @@ -244,7 +244,7 @@ impl Ratelimiter {
{
bucket.post_hook(
&response,
&req,
req,
&*self.ratelimit_callback.read(),
self.absolute_ratelimits,
)
Expand Down
11 changes: 9 additions & 2 deletions src/http/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ impl<'a> Request<'a> {
token: Option<&str>,
proxy: Option<&str>,
) -> Result<ReqwestRequestBuilder> {
// Build the multipart first, as to keep future size small.
let multipart = if let Some(multipart) = self.multipart {
Some(multipart.build_form().await?)
} else {
None
};

Comment on lines +78 to +84
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused here. The function call doesn't capture any locals, so why would it matter when it gets awaited? Or does it capture all of self?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function call doesn't use any of the locals, but the state machine for Request::build still needs to store the locals. By moving this back, we don't have to store the path/builder/headers in the state machine as there are no awaits after this.

let mut path = self.route.path().into_owned();

if let Some(proxy) = proxy {
Expand All @@ -100,9 +107,9 @@ impl<'a> Request<'a> {
);
}

if let Some(multipart) = self.multipart {
if let Some(multipart) = multipart {
// Setting multipart adds the content-length header.
builder = builder.multipart(multipart.build_form().await?);
builder = builder.multipart(multipart);
} else if let Some(bytes) = self.body {
headers.insert(CONTENT_LENGTH, bytes.len().into());
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
Expand Down
2 changes: 1 addition & 1 deletion src/model/channel/channel_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ impl GenericChannelId {
/// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding
/// reasons.
pub async fn send_message(self, http: &Http, builder: CreateMessage<'_>) -> Result<Message> {
builder.execute(http, self, None).await
builder.execute(http, self).await
}

/// Starts typing in the channel for an indefinite period of time.
Expand Down
4 changes: 3 additions & 1 deletion src/model/channel/guild_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,9 @@ impl GuildChannel {
/// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding
/// reasons.
pub async fn send_message(&self, http: &Http, builder: CreateMessage<'_>) -> Result<Message> {
builder.execute(http, self.id.widen(), Some(self.base.guild_id)).await
let mut message = self.id.widen().send_message(http, builder).await?;
message.guild_id = Some(self.base.guild_id);
Ok(message)
}

/// Retrieves [`Member`]s from the current channel.
Expand Down
4 changes: 3 additions & 1 deletion src/model/channel/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ impl GuildThread {
/// See [`CreateMessage::execute`] for a list of possible errors, and their corresponding
/// reasons.
pub async fn send_message(&self, http: &Http, builder: CreateMessage<'_>) -> Result<Message> {
builder.execute(http, self.id.widen(), Some(self.base.guild_id)).await
let mut message = self.id.widen().send_message(http, builder).await?;
message.guild_id = Some(self.base.guild_id);
Ok(message)
}
}

Expand Down
10 changes: 4 additions & 6 deletions src/model/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,12 +618,10 @@ impl UserId {
cache_http: impl CacheHttp,
builder: CreateMessage<'_>,
) -> Result<Message> {
self.create_dm_channel(&cache_http)
.await?
.id
.widen()
.send_message(cache_http.http(), builder)
.await
// Do not refactor this to a one liner. The PrivateChannel from `create_dm_channel`
// should be dropped before the `send_message` call to avoid bloating future sizes.
let dm_channel_id = self.create_dm_channel(&cache_http).await?.id;
dm_channel_id.widen().send_message(cache_http.http(), builder).await
}

/// This is an alias of [`Self::direct_message`].
Expand Down
Loading