Skip to content

Commit 82b0262

Browse files
authored
Shrink size and clean up Error (#2700)
Shrinks `size_of::<Error>` from 136 bytes to 64 bytes, while removing unused variants. This will improve performance for any method returning `Result<T>` where `T` is less than the size of `Error` as both `Result`'s `Ok` and `Err` have to be allocated stack space.
1 parent 373953b commit 82b0262

File tree

14 files changed

+96
-120
lines changed

14 files changed

+96
-120
lines changed

examples/testing/src/main.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
5757
let mut msg = channel_id
5858
.send_message(
5959
&ctx,
60-
CreateMessage::new().add_file(CreateAttachment::url(ctx, IMAGE_URL).await?),
60+
CreateMessage::new()
61+
.add_file(CreateAttachment::url(ctx, IMAGE_URL, "testing.png").await?),
6162
)
6263
.await?;
6364
// Pre-PR, this falsely triggered a MODEL_TYPE_CONVERT Discord error
@@ -69,13 +70,15 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
6970
let mut msg = channel_id
7071
.send_message(
7172
ctx,
72-
CreateMessage::new().add_file(CreateAttachment::url(ctx, IMAGE_URL).await?),
73+
CreateMessage::new()
74+
.add_file(CreateAttachment::url(ctx, IMAGE_URL, "testing.png").await?),
7375
)
7476
.await?;
7577
msg.edit(
7678
ctx,
7779
EditMessage::new().attachments(
78-
EditAttachments::keep_all(&msg).add(CreateAttachment::url(ctx, IMAGE_URL_2).await?),
80+
EditAttachments::keep_all(&msg)
81+
.add(CreateAttachment::url(ctx, IMAGE_URL_2, "testing1.png").await?),
7982
),
8083
)
8184
.await?;
@@ -196,7 +199,7 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
196199
ctx,
197200
CreateMessage::new()
198201
.flags(MessageFlags::IS_VOICE_MESSAGE)
199-
.add_file(CreateAttachment::url(ctx, audio_url).await?),
202+
.add_file(CreateAttachment::url(ctx, audio_url, "testing.ogg").await?),
200203
)
201204
.await?;
202205
} else if let Some(channel) = msg.content.strip_prefix("movetorootandback") {
@@ -231,7 +234,7 @@ async fn interaction(
231234
&ctx,
232235
CreateInteractionResponse::Message(
233236
CreateInteractionResponseMessage::new()
234-
.add_file(CreateAttachment::url(ctx, IMAGE_URL).await?),
237+
.add_file(CreateAttachment::url(ctx, IMAGE_URL, "testing.png").await?),
235238
),
236239
)
237240
.await?;
@@ -245,7 +248,7 @@ async fn interaction(
245248
&ctx,
246249
EditInteractionResponse::new().attachments(
247250
EditAttachments::keep_all(&msg)
248-
.add(CreateAttachment::url(ctx, IMAGE_URL_2).await?),
251+
.add(CreateAttachment::url(ctx, IMAGE_URL_2, "testing1.png").await?),
249252
),
250253
)
251254
.await?;
@@ -286,7 +289,7 @@ async fn interaction(
286289
ctx,
287290
CreateInteractionResponse::Message(
288291
CreateInteractionResponseMessage::new()
289-
.add_file(CreateAttachment::url(ctx, IMAGE_URL).await?),
292+
.add_file(CreateAttachment::url(ctx, IMAGE_URL, "testing.png").await?),
290293
),
291294
)
292295
.await?;
@@ -295,15 +298,15 @@ async fn interaction(
295298
.edit_response(
296299
ctx,
297300
EditInteractionResponse::new()
298-
.new_attachment(CreateAttachment::url(ctx, IMAGE_URL_2).await?),
301+
.new_attachment(CreateAttachment::url(ctx, IMAGE_URL_2, "testing1.png").await?),
299302
)
300303
.await?;
301304

302305
interaction
303306
.create_followup(
304307
ctx,
305308
CreateInteractionResponseFollowup::new()
306-
.add_file(CreateAttachment::url(ctx, IMAGE_URL).await?),
309+
.add_file(CreateAttachment::url(ctx, IMAGE_URL, "testing.png").await?),
307310
)
308311
.await?;
309312
} else if interaction.data.name == "editembeds" {

src/builder/create_attachment.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@ use std::path::Path;
33

44
use tokio::fs::File;
55
use tokio::io::AsyncReadExt;
6-
#[cfg(feature = "http")]
7-
use url::Url;
86

9-
use crate::all::Message;
10-
#[cfg(feature = "http")]
11-
use crate::error::Error;
12-
use crate::error::Result;
7+
#[allow(unused)] // Error is used in docs
8+
use crate::error::{Error, Result};
139
#[cfg(feature = "http")]
1410
use crate::http::Http;
11+
use crate::model::channel::Message;
1512
use crate::model::id::AttachmentId;
1613

1714
/// Enum that allows a user to pass a [`Path`] or a [`File`] type to [`send_files`]
@@ -81,20 +78,17 @@ impl<'a> CreateAttachment<'a> {
8178
///
8279
/// # Errors
8380
///
84-
/// [`Error::Url`] if the URL is invalid, [`Error::Http`] if downloading the data fails.
81+
/// Returns [`Error::Http`] if downloading the data fails.
8582
#[cfg(feature = "http")]
86-
pub async fn url(http: impl AsRef<Http>, url: &str) -> Result<Self> {
87-
let url = Url::parse(url).map_err(|_| Error::Url(url.to_string()))?;
88-
89-
let response = http.as_ref().client.get(url.clone()).send().await?;
83+
pub async fn url(
84+
http: impl AsRef<Http>,
85+
url: impl reqwest::IntoUrl,
86+
filename: impl Into<Cow<'static, str>>,
87+
) -> Result<Self> {
88+
let response = http.as_ref().client.get(url).send().await?;
9089
let data = response.bytes().await?.to_vec();
9190

92-
let filename = url
93-
.path_segments()
94-
.and_then(Iterator::last)
95-
.ok_or_else(|| Error::Url(url.to_string()))?;
96-
97-
Ok(CreateAttachment::bytes(data, filename.to_owned()))
91+
Ok(CreateAttachment::bytes(data, filename))
9892
}
9993

10094
/// Converts the stored data to the base64 representation.

src/client/error.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@ use std::fmt;
1212
pub enum Error {
1313
/// When a shard has completely failed to reboot after resume and/or reconnect attempts.
1414
ShardBootFailure,
15-
/// When all shards that the client is responsible for have shutdown with an error.
16-
Shutdown,
1715
}
1816

1917
impl fmt::Display for Error {
2018
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2119
match self {
2220
Self::ShardBootFailure => f.write_str("Failed to (re-)boot a shard"),
23-
Self::Shutdown => f.write_str("The clients shards shutdown"),
2421
}
2522
}
2623
}

src/client/mod.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ use crate::internal::prelude::*;
5757
#[cfg(feature = "gateway")]
5858
use crate::model::gateway::GatewayIntents;
5959
use crate::model::id::ApplicationId;
60+
#[cfg(feature = "voice")]
61+
use crate::model::id::UserId;
6062
use crate::model::user::OnlineStatus;
6163
use crate::utils::check_shard_total;
6264

@@ -633,7 +635,9 @@ impl Client {
633635
///
634636
/// # Errors
635637
///
636-
/// Returns a [`ClientError::Shutdown`] when all shards have shutdown due to an error.
638+
/// Returns [`Error::Gateway`] when all shards have shutdown due to an error.
639+
/// Returns [`Error::Http`] if fetching the current User fails when initialising a voice
640+
/// manager.
637641
///
638642
/// [gateway docs]: crate::gateway#sharding
639643
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
@@ -674,7 +678,9 @@ impl Client {
674678
///
675679
/// # Errors
676680
///
677-
/// Returns a [`ClientError::Shutdown`] when all shards have shutdown due to an error.
681+
/// Returns [`Error::Gateway`] when all shards have shutdown due to an error.
682+
/// Returns [`Error::Http`] if fetching the current User fails when initialising a voice
683+
/// manager.
678684
///
679685
/// [gateway docs]: crate::gateway#sharding
680686
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
@@ -738,7 +744,9 @@ impl Client {
738744
///
739745
/// # Errors
740746
///
741-
/// Returns a [`ClientError::Shutdown`] when all shards have shutdown due to an error.
747+
/// Returns [`Error::Gateway`] when all shards have shutdown due to an error.
748+
/// Returns [`Error::Http`] if fetching the current User fails when initialising a voice
749+
/// manager.
742750
///
743751
/// [gateway docs]: crate::gateway#sharding
744752
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
@@ -779,7 +787,9 @@ impl Client {
779787
///
780788
/// # Errors
781789
///
782-
/// Returns a [`ClientError::Shutdown`] when all shards have shutdown due to an error.
790+
/// Returns [`Error::Gateway`] when all shards have shutdown due to an error.
791+
/// Returns [`Error::Http`] if fetching the current User fails when initialising a voice
792+
/// manager.
783793
///
784794
/// [Gateway docs]: crate::gateway#sharding
785795
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
@@ -820,7 +830,9 @@ impl Client {
820830
///
821831
/// # Errors
822832
///
823-
/// Returns a [`ClientError::Shutdown`] when all shards have shutdown due to an error.
833+
/// Returns [`Error::Gateway`] when all shards have shutdown due to an error.
834+
/// Returns [`Error::Http`] if fetching the current User fails when initialising a voice
835+
/// manager.
824836
///
825837
/// [Gateway docs]: crate::gateway#sharding
826838
#[cfg_attr(feature = "tracing_instrument", instrument(skip(self)))]
@@ -837,9 +849,25 @@ impl Client {
837849
) -> Result<()> {
838850
#[cfg(feature = "voice")]
839851
if let Some(voice_manager) = &self.voice_manager {
840-
let user = self.http.get_current_user().await?;
852+
#[cfg(feature = "cache")]
853+
let cache_user_id = {
854+
let cache_user = self.cache.current_user();
855+
if cache_user.id == UserId::default() {
856+
Some(cache_user.id)
857+
} else {
858+
None
859+
}
860+
};
861+
862+
#[cfg(not(feature = "cache"))]
863+
let cache_user_id: Option<UserId> = None;
864+
865+
let user_id = match cache_user_id {
866+
Some(u) => u,
867+
None => self.http.get_current_user().await?.id,
868+
};
841869

842-
voice_manager.initialise(total_shards, user.id).await;
870+
voice_manager.initialise(total_shards, user_id).await;
843871
}
844872

845873
let init = end_shard - start_shard + 1;

src/error.rs

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::error::Error as StdError;
2-
use std::fmt::{self, Error as FormatError};
2+
use std::fmt;
33
use std::io::Error as IoError;
44

55
#[cfg(feature = "http")]
@@ -31,10 +31,6 @@ pub type Result<T, E = Error> = StdResult<T, E>;
3131
#[derive(Debug)]
3232
#[non_exhaustive]
3333
pub enum Error {
34-
/// An error while decoding a payload.
35-
Decode(&'static str, Value),
36-
/// There was an error with a format.
37-
Format(FormatError),
3834
/// An [`std::io`] error.
3935
Io(IoError),
4036
#[cfg_attr(not(feature = "simd_json"), doc = "An error from the [`serde_json`] crate.")]
@@ -44,20 +40,6 @@ pub enum Error {
4440
///
4541
/// [`model`]: crate::model
4642
Model(ModelError),
47-
/// The input is not in the specified range. Returned by [`GuildId::members`],
48-
/// [`Guild::members`] and [`PartialGuild::members`]
49-
///
50-
/// (param_name, value, range_min, range_max)
51-
///
52-
/// [`GuildId::members`]: crate::model::id::GuildId::members
53-
/// [`Guild::members`]: crate::model::guild::Guild::members
54-
/// [`PartialGuild::members`]: crate::model::guild::PartialGuild::members
55-
NotInRange(&'static str, u64, u64, u64),
56-
/// Some other error. This is only used for "Expected value \<TYPE\>" errors, when a more
57-
/// detailed error can not be easily provided via the [`Error::Decode`] variant.
58-
Other(&'static str),
59-
/// An error from the [`url`] crate.
60-
Url(String),
6143
/// A [client] error.
6244
///
6345
/// [client]: crate::client
@@ -75,13 +57,7 @@ pub enum Error {
7557
Http(HttpError),
7658
/// An error from the `tungstenite` crate.
7759
#[cfg(feature = "gateway")]
78-
Tungstenite(TungsteniteError),
79-
}
80-
81-
impl From<FormatError> for Error {
82-
fn from(e: FormatError) -> Error {
83-
Error::Format(e)
84-
}
60+
Tungstenite(Box<TungsteniteError>),
8561
}
8662

8763
#[cfg(feature = "gateway")]
@@ -112,7 +88,7 @@ impl From<ModelError> for Error {
11288
#[cfg(feature = "gateway")]
11389
impl From<TungsteniteError> for Error {
11490
fn from(e: TungsteniteError) -> Error {
115-
Error::Tungstenite(e)
91+
Error::Tungstenite(Box::new(e))
11692
}
11793
}
11894

@@ -140,13 +116,9 @@ impl From<ReqwestError> for Error {
140116
impl fmt::Display for Error {
141117
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142118
match self {
143-
Self::Decode(msg, _) | Self::Other(msg) => f.write_str(msg),
144-
Self::NotInRange(..) => f.write_str("Input is not in the specified range"),
145-
Self::Format(inner) => fmt::Display::fmt(&inner, f),
146119
Self::Io(inner) => fmt::Display::fmt(&inner, f),
147120
Self::Json(inner) => fmt::Display::fmt(&inner, f),
148121
Self::Model(inner) => fmt::Display::fmt(&inner, f),
149-
Self::Url(msg) => f.write_str(msg),
150122
#[cfg(feature = "client")]
151123
Self::Client(inner) => fmt::Display::fmt(&inner, f),
152124
#[cfg(feature = "gateway")]
@@ -163,7 +135,6 @@ impl StdError for Error {
163135
#[cfg_attr(feature = "tracing_instrument", instrument)]
164136
fn source(&self) -> Option<&(dyn StdError + 'static)> {
165137
match self {
166-
Self::Format(inner) => Some(inner),
167138
Self::Io(inner) => Some(inner),
168139
Self::Json(inner) => Some(inner),
169140
Self::Model(inner) => Some(inner),

src/framework/standard/help_commands.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ fn flatten_group_to_string(
897897
group: &GroupCommandsPair,
898898
nest_level: usize,
899899
help_options: &HelpOptions,
900-
) -> Result<(), Error> {
900+
) -> Result<(), std::fmt::Error> {
901901
let repeated_indent_str = help_options.indention_prefix.repeat(nest_level);
902902

903903
if nest_level > 0 {
@@ -1002,7 +1002,8 @@ async fn send_grouped_commands_embed(
10021002
for group in groups {
10031003
let mut embed_text = String::default();
10041004

1005-
flatten_group_to_string(&mut embed_text, group, 0, help_options)?;
1005+
flatten_group_to_string(&mut embed_text, group, 0, help_options)
1006+
.expect("String::write should never fail");
10061007

10071008
embed = embed.field(group.name, embed_text, true);
10081009
}

src/gateway/bridge/shard_runner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ impl ShardRunner {
398398
async fn recv_event(&mut self) -> Result<(Option<Event>, Option<ShardAction>, bool)> {
399399
let gw_event = match self.shard.client.recv_json().await {
400400
Ok(inner) => Ok(inner),
401-
Err(Error::Tungstenite(TungsteniteError::Io(_))) => {
401+
Err(Error::Tungstenite(tung_err)) if matches!(*tung_err, TungsteniteError::Io(_)) => {
402402
debug!("Attempting to auto-reconnect");
403403

404404
match self.shard.reconnection_type() {

src/gateway/shard.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,16 @@ impl Shard {
201201
Ok(())
202202
},
203203
Err(why) => {
204-
match why {
205-
Error::Tungstenite(TungsteniteError::Io(err)) => {
204+
if let Error::Tungstenite(err) = &why {
205+
if let TungsteniteError::Io(err) = &**err {
206206
if err.raw_os_error() != Some(32) {
207207
debug!("[{:?}] Err heartbeating: {:?}", self.shard_info, err);
208+
return Err(Error::Gateway(GatewayError::HeartbeatFailed));
208209
}
209-
},
210-
other => {
211-
warn!("[{:?}] Other err w/ keepalive: {:?}", self.shard_info, other);
212-
},
210+
}
213211
}
214212

213+
warn!("[{:?}] Other err w/ keepalive: {:?}", self.shard_info, why);
215214
Err(Error::Gateway(GatewayError::HeartbeatFailed))
216215
},
217216
}

0 commit comments

Comments
 (0)