use twilight_model::{
channel::{
message::{embed::EmbedField, Embed, MessageActivityType, MessageFlags, MessageType},
Attachment, Message,
},
gateway::payload::incoming::MessageUpdate,
id::{
marker::{
ApplicationMarker, AttachmentMarker, ChannelMarker, GenericMarker, GuildMarker,
MessageMarker, UserMarker, WebhookMarker,
},
Id,
},
util::{ImageHash, Timestamp},
};
use crate::unique_id;
#[derive(Clone, Debug)]
#[cfg_attr(feature = "tests", derive(PartialEq, Eq))]
pub struct CachedEmbedField {
pub embed_id: Id<GenericMarker>,
pub inline: bool,
pub name: String,
pub value: String,
}
impl CachedEmbedField {
#[allow(clippy::missing_const_for_fn)]
#[must_use]
pub fn from_embed_field(embed_field: EmbedField, embed_id: Id<GenericMarker>) -> Self {
Self {
embed_id,
inline: embed_field.inline,
name: embed_field.name,
value: embed_field.value,
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "tests", derive(PartialEq, Eq))]
pub struct CachedEmbed {
pub id: Id<GenericMarker>,
pub message_id: Id<MessageMarker>,
pub author_icon_url: Option<String>,
pub author_name: Option<String>,
pub author_proxy_icon_url: Option<String>,
pub author_url: Option<String>,
pub color: Option<u32>,
pub description: Option<String>,
pub footer_icon_url: Option<String>,
pub footer_proxy_icon_url: Option<String>,
pub footer_text: Option<String>,
pub image_height: Option<u64>,
pub image_proxy_url: Option<String>,
pub image_url: Option<String>,
pub image_width: Option<u64>,
pub kind: String,
pub provider_name: Option<String>,
pub provider_url: Option<String>,
pub thumbnail_height: Option<u64>,
pub thumbnail_proxy_url: Option<String>,
pub thumbnail_url: Option<String>,
pub thumbnail_width: Option<u64>,
pub timestamp: Option<Timestamp>,
pub title: Option<String>,
pub url: Option<String>,
pub video_height: Option<u64>,
pub video_proxy_url: Option<String>,
pub video_url: Option<String>,
pub video_width: Option<u64>,
}
impl CachedEmbed {
#[allow(clippy::cast_sign_loss, clippy::as_conversions)]
#[must_use]
pub fn from_embed(embed: Embed, message_id: Id<MessageMarker>) -> Self {
Self {
id: Id::new(unique_id() as u64),
message_id,
author_icon_url: embed
.author
.as_ref()
.and_then(|author| author.icon_url.clone()),
author_name: embed.author.as_ref().map(|author| author.name.clone()),
author_proxy_icon_url: embed
.author
.as_ref()
.and_then(|author| author.icon_url.clone()),
author_url: embed.author.as_ref().and_then(|author| author.url.clone()),
color: embed.color,
description: embed.description,
footer_icon_url: embed
.footer
.as_ref()
.and_then(|footer| footer.icon_url.clone()),
footer_proxy_icon_url: embed
.footer
.as_ref()
.and_then(|footer| footer.proxy_icon_url.clone()),
footer_text: embed.footer.as_ref().map(|footer| footer.text.clone()),
image_height: embed.image.as_ref().and_then(|image| image.height),
image_proxy_url: embed
.image
.as_ref()
.and_then(|image| image.proxy_url.clone()),
image_url: embed.image.as_ref().map(|image| image.url.clone()),
image_width: embed.image.as_ref().and_then(|image| image.width),
kind: embed.kind,
provider_name: embed
.provider
.as_ref()
.and_then(|provider| provider.name.clone()),
provider_url: embed
.provider
.as_ref()
.and_then(|provider| provider.url.clone()),
thumbnail_height: embed
.thumbnail
.as_ref()
.and_then(|thumbnail| thumbnail.height),
thumbnail_proxy_url: embed
.thumbnail
.as_ref()
.and_then(|thumbnail| thumbnail.proxy_url.clone()),
thumbnail_url: embed
.thumbnail
.as_ref()
.map(|thumbnail| thumbnail.url.clone()),
thumbnail_width: embed
.thumbnail
.as_ref()
.and_then(|thumbnail| thumbnail.width),
timestamp: embed.timestamp,
title: embed.title,
url: embed.url,
video_height: embed.video.as_ref().and_then(|video| video.height),
video_proxy_url: embed
.video
.as_ref()
.and_then(|video| video.proxy_url.clone()),
video_url: embed.video.as_ref().and_then(|video| video.url.clone()),
video_width: embed.video.as_ref().and_then(|video| video.width),
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "tests", derive(PartialEq, Eq))]
pub struct CachedAttachment {
pub message_id: Id<MessageMarker>,
pub content_type: Option<String>,
pub ephemeral: bool,
pub filename: String,
pub description: Option<String>,
pub height: Option<u64>,
pub id: Id<AttachmentMarker>,
pub proxy_url: String,
pub size: u64,
pub url: String,
pub width: Option<u64>,
}
impl CachedAttachment {
#[allow(clippy::missing_const_for_fn)]
#[must_use]
pub fn from_attachment(attachment: Attachment, message_id: Id<MessageMarker>) -> Self {
Self {
message_id,
content_type: attachment.content_type,
ephemeral: attachment.ephemeral,
filename: attachment.filename,
description: attachment.description,
height: attachment.height,
id: attachment.id,
proxy_url: attachment.proxy_url,
size: attachment.size,
url: attachment.url,
width: attachment.width,
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "tests", derive(PartialEq, Eq))]
pub struct CachedMessage {
pub activity_type: Option<MessageActivityType>,
pub activity_party_id: Option<String>,
pub application_cover_image: Option<ImageHash>,
pub application_description: Option<String>,
pub application_icon: Option<ImageHash>,
pub application_id: Option<Id<ApplicationMarker>>,
pub application_name: Option<String>,
pub interaction_application_id: Option<Id<ApplicationMarker>>,
pub author: Id<UserMarker>,
pub channel_id: Id<ChannelMarker>,
pub content: String,
pub edited_timestamp: Option<Timestamp>,
pub flags: Option<MessageFlags>,
pub guild_id: Option<Id<GuildMarker>>,
pub id: Id<MessageMarker>,
pub kind: MessageType,
pub mention_everyone: bool,
pub pinned: bool,
pub reference_channel_id: Option<Id<ChannelMarker>>,
pub reference_guild_id: Option<Id<GuildMarker>>,
pub reference_message_id: Option<Id<MessageMarker>>,
pub reference_fail_if_not_exists: Option<bool>,
pub referenced_message: Option<Id<MessageMarker>>,
pub timestamp: Timestamp,
pub thread: Option<Id<ChannelMarker>>,
pub tts: bool,
pub webhook_id: Option<Id<WebhookMarker>>,
}
impl CachedMessage {
pub fn update(&mut self, message: &MessageUpdate) {
if let Some(content) = &message.content {
self.content.clone_from(content);
}
if message.edited_timestamp.is_some() {
self.edited_timestamp = message.edited_timestamp;
}
if let Some(mentions) = message.mention_everyone {
self.mention_everyone = mentions;
}
if let Some(pinned) = message.pinned {
self.pinned = pinned;
}
}
}
impl From<&Message> for CachedMessage {
fn from(message: &Message) -> Self {
Self {
activity_type: message.activity.as_ref().map(|activity| activity.kind),
activity_party_id: message
.activity
.as_ref()
.and_then(|activity| activity.party_id.clone()),
application_cover_image: message
.application
.as_ref()
.and_then(|application| application.cover_image),
application_description: message
.application
.as_ref()
.map(|application| application.description.clone()),
application_icon: message
.application
.as_ref()
.and_then(|application| application.icon),
application_id: message
.application
.as_ref()
.map(|application| application.id),
application_name: message
.application
.as_ref()
.map(|application| application.name.clone()),
interaction_application_id: message.application_id,
author: message.author.id,
channel_id: message.channel_id,
content: message.content.clone(),
edited_timestamp: message.edited_timestamp,
guild_id: message.guild_id,
id: message.id,
kind: message.kind,
mention_everyone: message.mention_everyone,
pinned: message.pinned,
reference_channel_id: message
.reference
.as_ref()
.and_then(|reference| reference.channel_id),
reference_guild_id: message
.reference
.as_ref()
.and_then(|reference| reference.guild_id),
reference_message_id: message
.reference
.as_ref()
.and_then(|reference| reference.message_id),
reference_fail_if_not_exists: message
.reference
.as_ref()
.and_then(|reference| reference.fail_if_not_exists),
referenced_message: message
.referenced_message
.as_ref()
.map(|reference| reference.id),
timestamp: message.timestamp,
thread: message.thread.as_ref().map(|thread| thread.id),
tts: message.tts,
flags: message.flags,
webhook_id: message.webhook_id,
}
}
}