Skip to content

Commit 756ddf4

Browse files
authored
Make Message{Id}::link return an intermediate struct for lazily formatting the link (#3415)
Users can still convert it to a `String` using `ToString::to_string`, but if they happen to pass it to a formatting macro such as `format!`, they will avoid a heap allocation that would have otherwise occurred for the link, which is the motivation for this change.
1 parent 77a74e0 commit 756ddf4

File tree

1 file changed

+43
-6
lines changed

1 file changed

+43
-6
lines changed

src/model/channel/message.rs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
#[cfg(feature = "model")]
44
use std::borrow::Cow;
5+
#[cfg(feature = "model")]
6+
use std::fmt::Display;
57

68
use nonmax::NonMaxU64;
79

@@ -574,7 +576,7 @@ impl Message {
574576
/// Returns a link referencing this message. When clicked, users will jump to the message. The
575577
/// link will be valid for messages in either private channels or guilds.
576578
#[must_use]
577-
pub fn link(&self) -> String {
579+
pub fn link(&self) -> MessageLink {
578580
self.id.link(self.channel_id, self.guild_id)
579581
}
580582

@@ -966,16 +968,51 @@ bitflags! {
966968
}
967969
}
968970

971+
/// Uniquely identifies a message.
972+
///
973+
/// Implements Display to format to a url to the message.
974+
/// When clicked, users will jump to the message. The link will be valid
975+
/// for messages in either private channels or guilds.
976+
#[derive(Clone, Copy, Eq, PartialEq)]
977+
#[cfg(feature = "model")]
978+
pub struct MessageLink {
979+
/// The id of the message
980+
pub message_id: MessageId,
981+
/// The id of the channel or thread the message is in
982+
pub channel_id: GenericChannelId,
983+
/// The id of the guild if it's a guild message
984+
pub guild_id: Option<GuildId>,
985+
}
986+
987+
#[cfg(feature = "model")]
988+
impl Display for MessageLink {
989+
#[inline]
990+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
991+
let MessageLink {
992+
message_id,
993+
channel_id,
994+
guild_id,
995+
} = self;
996+
997+
f.write_str("https://discord.com/channels/")?;
998+
if let Some(guild_id) = guild_id {
999+
write!(f, "/{guild_id}/{channel_id}/{message_id}")
1000+
} else {
1001+
write!(f, "/@me/{channel_id}/{message_id}")
1002+
}
1003+
}
1004+
}
1005+
9691006
#[cfg(feature = "model")]
9701007
impl MessageId {
9711008
/// Returns a link referencing this message. When clicked, users will jump to the message. The
9721009
/// link will be valid for messages in either private channels or guilds.
9731010
#[must_use]
974-
pub fn link(self, channel_id: GenericChannelId, guild_id: Option<GuildId>) -> String {
975-
if let Some(guild_id) = guild_id {
976-
format!("https://discord.com/channels/{guild_id}/{channel_id}/{self}")
977-
} else {
978-
format!("https://discord.com/channels/@me/{channel_id}/{self}")
1011+
pub fn link(self, channel_id: GenericChannelId, guild_id: Option<GuildId>) -> MessageLink {
1012+
MessageLink {
1013+
message_id: self,
1014+
channel_id,
1015+
guild_id,
9791016
}
9801017
}
9811018
}

0 commit comments

Comments
 (0)