use std::fmt::{Display, Formatter, Result as FmtResult};
use twilight_model::{
channel::{
CategoryChannel, Channel, Group, GuildChannel, PrivateChannel, TextChannel, VoiceChannel,
},
guild::{Emoji, Member, Role},
id::{ChannelId, EmojiId, RoleId, UserId},
user::{CurrentUser, User},
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct MentionFormat<T>(T);
impl Display for MentionFormat<ChannelId> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_fmt(format_args!("<#{}>", self.0))
}
}
impl Display for MentionFormat<EmojiId> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_fmt(format_args!("<:emoji:{}>", self.0))
}
}
impl Display for MentionFormat<RoleId> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_fmt(format_args!("<@&{}>", self.0))
}
}
impl Display for MentionFormat<UserId> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_fmt(format_args!("<@{}>", self.0))
}
}
pub trait Mention<T> {
fn mention(&self) -> MentionFormat<T>;
}
impl Mention<ChannelId> for ChannelId {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(*self)
}
}
impl Mention<ChannelId> for &'_ ChannelId {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
impl Mention<ChannelId> for CategoryChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(self.id)
}
}
impl Mention<ChannelId> for &'_ CategoryChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
impl Mention<ChannelId> for Channel {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(self.id())
}
}
impl Mention<ChannelId> for &'_ Channel {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
impl Mention<UserId> for CurrentUser {
fn mention(&self) -> MentionFormat<UserId> {
MentionFormat(self.id)
}
}
impl Mention<UserId> for &'_ CurrentUser {
fn mention(&self) -> MentionFormat<UserId> {
(*self).mention()
}
}
impl Mention<EmojiId> for EmojiId {
fn mention(&self) -> MentionFormat<EmojiId> {
MentionFormat(*self)
}
}
impl Mention<EmojiId> for &'_ EmojiId {
fn mention(&self) -> MentionFormat<EmojiId> {
(*self).mention()
}
}
impl Mention<EmojiId> for Emoji {
fn mention(&self) -> MentionFormat<EmojiId> {
MentionFormat(self.id)
}
}
impl Mention<EmojiId> for &'_ Emoji {
fn mention(&self) -> MentionFormat<EmojiId> {
(*self).mention()
}
}
impl Mention<ChannelId> for Group {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(self.id)
}
}
impl Mention<ChannelId> for &'_ Group {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
impl Mention<ChannelId> for GuildChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(self.id())
}
}
impl Mention<ChannelId> for &'_ GuildChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
impl Mention<UserId> for Member {
fn mention(&self) -> MentionFormat<UserId> {
MentionFormat(self.user.id)
}
}
impl Mention<UserId> for &'_ Member {
fn mention(&self) -> MentionFormat<UserId> {
(*self).mention()
}
}
impl Mention<ChannelId> for PrivateChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(self.id)
}
}
impl Mention<ChannelId> for &'_ PrivateChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
impl Mention<RoleId> for RoleId {
fn mention(&self) -> MentionFormat<RoleId> {
MentionFormat(*self)
}
}
impl Mention<RoleId> for &'_ RoleId {
fn mention(&self) -> MentionFormat<RoleId> {
(*self).mention()
}
}
impl Mention<RoleId> for Role {
fn mention(&self) -> MentionFormat<RoleId> {
MentionFormat(self.id)
}
}
impl Mention<RoleId> for &'_ Role {
fn mention(&self) -> MentionFormat<RoleId> {
(*self).mention()
}
}
impl Mention<ChannelId> for TextChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(self.id)
}
}
impl Mention<ChannelId> for &'_ TextChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
impl Mention<UserId> for UserId {
fn mention(&self) -> MentionFormat<UserId> {
MentionFormat(*self)
}
}
impl Mention<UserId> for &'_ UserId {
fn mention(&self) -> MentionFormat<UserId> {
(*self).mention()
}
}
impl Mention<UserId> for User {
fn mention(&self) -> MentionFormat<UserId> {
MentionFormat(self.id)
}
}
impl Mention<UserId> for &'_ User {
fn mention(&self) -> MentionFormat<UserId> {
(*self).mention()
}
}
impl Mention<ChannelId> for VoiceChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
MentionFormat(self.id)
}
}
impl Mention<ChannelId> for &'_ VoiceChannel {
fn mention(&self) -> MentionFormat<ChannelId> {
(*self).mention()
}
}
#[cfg(test)]
mod tests {
use super::{Mention, MentionFormat};
use static_assertions::assert_impl_all;
use std::fmt::{Debug, Display};
use twilight_model::{
channel::{
CategoryChannel, Channel, Group, GuildChannel, PrivateChannel, TextChannel,
VoiceChannel,
},
guild::{Emoji, Member, Role},
id::{ChannelId, EmojiId, RoleId, UserId},
user::{CurrentUser, User},
};
assert_impl_all!(MentionFormat<()>: Clone, Copy, Debug, Eq, PartialEq, Send, Sync);
assert_impl_all!(MentionFormat<ChannelId>: Clone, Copy, Debug, Display, Eq, PartialEq, Send, Sync);
assert_impl_all!(MentionFormat<EmojiId>: Clone, Copy, Debug, Display, Eq, PartialEq, Send, Sync);
assert_impl_all!(MentionFormat<RoleId>: Clone, Copy, Debug, Display, Eq, PartialEq, Send, Sync);
assert_impl_all!(MentionFormat<UserId>: Clone, Copy, Debug, Display, Eq, PartialEq, Send, Sync);
assert_impl_all!(ChannelId: Mention<ChannelId>);
assert_impl_all!(&'static ChannelId: Mention<ChannelId>);
assert_impl_all!(CategoryChannel: Mention<ChannelId>);
assert_impl_all!(&'static CategoryChannel: Mention<ChannelId>);
assert_impl_all!(Channel: Mention<ChannelId>);
assert_impl_all!(&'static Channel: Mention<ChannelId>);
assert_impl_all!(CurrentUser: Mention<UserId>);
assert_impl_all!(&'static CurrentUser: Mention<UserId>);
assert_impl_all!(EmojiId: Mention<EmojiId>);
assert_impl_all!(&'static EmojiId: Mention<EmojiId>);
assert_impl_all!(Emoji: Mention<EmojiId>);
assert_impl_all!(&'static Emoji: Mention<EmojiId>);
assert_impl_all!(Group: Mention<ChannelId>);
assert_impl_all!(&'static Group: Mention<ChannelId>);
assert_impl_all!(GuildChannel: Mention<ChannelId>);
assert_impl_all!(&'static GuildChannel: Mention<ChannelId>);
assert_impl_all!(Member: Mention<UserId>);
assert_impl_all!(&'static Member: Mention<UserId>);
assert_impl_all!(PrivateChannel: Mention<ChannelId>);
assert_impl_all!(&'static PrivateChannel: Mention<ChannelId>);
assert_impl_all!(RoleId: Mention<RoleId>);
assert_impl_all!(&'static RoleId: Mention<RoleId>);
assert_impl_all!(Role: Mention<RoleId>);
assert_impl_all!(&'static Role: Mention<RoleId>);
assert_impl_all!(TextChannel: Mention<ChannelId>);
assert_impl_all!(&'static TextChannel: Mention<ChannelId>);
assert_impl_all!(UserId: Mention<UserId>);
assert_impl_all!(&'static UserId: Mention<UserId>);
assert_impl_all!(User: Mention<UserId>);
assert_impl_all!(&'static User: Mention<UserId>);
assert_impl_all!(VoiceChannel: Mention<ChannelId>);
assert_impl_all!(&'static VoiceChannel: Mention<ChannelId>);
#[test]
fn test_mention_format_channel_id() {
assert_eq!("<#123>", ChannelId(123).mention().to_string());
}
#[test]
fn test_mention_format_emoji_id() {
assert_eq!("<:emoji:123>", EmojiId(123).mention().to_string());
}
#[test]
fn test_mention_format_role_id() {
assert_eq!("<@&123>", RoleId(123).mention().to_string());
}
#[test]
fn test_mention_format_user_id() {
assert_eq!("<@123>", UserId(123).mention().to_string());
}
}