use serde::Serialize;
use twilight_model::{
application::interaction::InteractionType,
channel::{
message::{
sticker::MessageSticker, Component, Embed, Message, MessageActivity,
MessageApplication, MessageFlags, MessageInteraction, MessageReference, MessageType,
Reaction,
},
Attachment, ChannelMention,
},
guild::PartialMember,
id::{
marker::{
ApplicationMarker, ChannelMarker, GuildMarker, InteractionMarker, MessageMarker,
RoleMarker, UserMarker, WebhookMarker,
},
Id,
},
util::Timestamp,
};
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CachedMessageInteraction {
id: Id<InteractionMarker>,
#[serde(rename = "type")]
kind: InteractionType,
name: String,
user_id: Id<UserMarker>,
}
impl CachedMessageInteraction {
pub const fn id(&self) -> Id<InteractionMarker> {
self.id
}
pub const fn kind(&self) -> InteractionType {
self.kind
}
pub fn name(&self) -> &str {
&self.name
}
pub const fn user_id(&self) -> Id<UserMarker> {
self.user_id
}
#[allow(clippy::missing_const_for_fn)]
pub(crate) fn from_model(message_interaction: MessageInteraction) -> Self {
let MessageInteraction {
id,
kind,
member: _,
name,
user,
} = message_interaction;
Self {
id,
kind,
name,
user_id: user.id,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct CachedMessage {
activity: Option<MessageActivity>,
application: Option<MessageApplication>,
application_id: Option<Id<ApplicationMarker>>,
pub(crate) attachments: Vec<Attachment>,
author: Id<UserMarker>,
channel_id: Id<ChannelMarker>,
components: Vec<Component>,
pub(crate) content: String,
pub(crate) edited_timestamp: Option<Timestamp>,
pub(crate) embeds: Vec<Embed>,
flags: Option<MessageFlags>,
guild_id: Option<Id<GuildMarker>>,
id: Id<MessageMarker>,
interaction: Option<CachedMessageInteraction>,
kind: MessageType,
member: Option<PartialMember>,
mention_channels: Vec<ChannelMention>,
pub(crate) mention_everyone: bool,
pub(crate) mention_roles: Vec<Id<RoleMarker>>,
pub(crate) mentions: Vec<Id<UserMarker>>,
pub(crate) pinned: bool,
pub(crate) reactions: Vec<Reaction>,
reference: Option<MessageReference>,
sticker_items: Vec<MessageSticker>,
thread_id: Option<Id<ChannelMarker>>,
pub(crate) timestamp: Timestamp,
pub(crate) tts: bool,
webhook_id: Option<Id<WebhookMarker>>,
}
impl CachedMessage {
pub const fn activity(&self) -> Option<&MessageActivity> {
self.activity.as_ref()
}
pub const fn application(&self) -> Option<&MessageApplication> {
self.application.as_ref()
}
pub const fn application_id(&self) -> Option<Id<ApplicationMarker>> {
self.application_id
}
pub fn attachments(&self) -> &[Attachment] {
&self.attachments
}
pub const fn author(&self) -> Id<UserMarker> {
self.author
}
pub const fn channel_id(&self) -> Id<ChannelMarker> {
self.channel_id
}
pub fn components(&self) -> &[Component] {
&self.components
}
pub fn content(&self) -> &str {
&self.content
}
pub const fn edited_timestamp(&self) -> Option<Timestamp> {
self.edited_timestamp
}
pub fn embeds(&self) -> &[Embed] {
&self.embeds
}
pub const fn flags(&self) -> Option<MessageFlags> {
self.flags
}
pub const fn guild_id(&self) -> Option<Id<GuildMarker>> {
self.guild_id
}
pub const fn id(&self) -> Id<MessageMarker> {
self.id
}
pub const fn interaction(&self) -> Option<&CachedMessageInteraction> {
self.interaction.as_ref()
}
pub const fn kind(&self) -> MessageType {
self.kind
}
pub const fn member(&self) -> Option<&PartialMember> {
self.member.as_ref()
}
pub fn mention_channels(&self) -> &[ChannelMention] {
&self.mention_channels
}
pub const fn mention_everyone(&self) -> bool {
self.mention_everyone
}
pub fn mention_roles(&self) -> &[Id<RoleMarker>] {
&self.mention_roles
}
pub fn mentions(&self) -> &[Id<UserMarker>] {
&self.mentions
}
pub const fn pinned(&self) -> bool {
self.pinned
}
pub fn reactions(&self) -> &[Reaction] {
&self.reactions
}
pub const fn reference(&self) -> Option<&MessageReference> {
self.reference.as_ref()
}
pub fn sticker_items(&self) -> &[MessageSticker] {
&self.sticker_items
}
pub const fn thread_id(&self) -> Option<Id<ChannelMarker>> {
self.thread_id
}
pub const fn timestamp(&self) -> Timestamp {
self.timestamp
}
pub const fn tts(&self) -> bool {
self.tts
}
pub const fn webhook_id(&self) -> Option<Id<WebhookMarker>> {
self.webhook_id
}
pub(crate) fn from_model(message: Message) -> Self {
let Message {
activity,
application,
application_id,
attachments,
author,
channel_id,
components,
content,
edited_timestamp,
embeds,
flags,
guild_id,
id,
interaction,
kind,
member,
mention_channels,
mention_everyone,
mention_roles,
mentions,
pinned,
reactions,
reference,
referenced_message: _,
sticker_items,
timestamp,
thread,
tts,
webhook_id,
} = message;
Self {
id,
activity,
application,
application_id,
attachments,
author: author.id,
channel_id,
components,
content,
edited_timestamp,
embeds,
flags,
guild_id,
interaction: interaction.map(CachedMessageInteraction::from_model),
kind,
member,
mention_channels,
mention_everyone,
mention_roles,
mentions: mentions.into_iter().map(|mention| mention.id).collect(),
pinned,
reactions,
reference,
sticker_items,
thread_id: thread.map(|thread| thread.id),
timestamp,
tts,
webhook_id,
}
}
}
impl From<Message> for CachedMessage {
fn from(message: Message) -> Self {
Self::from_model(message)
}
}
#[cfg(test)]
mod tests {
use super::{CachedMessage, CachedMessageInteraction};
use serde::Serialize;
use static_assertions::{assert_fields, assert_impl_all};
use std::fmt::Debug;
use twilight_model::channel::message::Message;
assert_fields!(
CachedMessage: activity,
application,
application_id,
attachments,
author,
channel_id,
components,
content,
edited_timestamp,
embeds,
flags,
guild_id,
id,
interaction,
kind,
member,
mention_channels,
mention_everyone,
mention_roles,
mentions,
pinned,
reactions,
reference,
sticker_items,
thread_id,
timestamp,
tts,
webhook_id
);
assert_impl_all!(
CachedMessage: Clone,
Debug,
Eq,
From<Message>,
PartialEq,
Send,
Serialize,
Sync,
);
assert_fields!(CachedMessageInteraction: id, kind, name, user_id);
assert_impl_all!(
CachedMessageInteraction: Clone,
Debug,
Eq,
PartialEq,
Send,
Serialize,
Sync,
);
}