use crate::{
channel::Attachment,
id::{Id, marker::GuildMarker},
util::Timestamp,
};
use super::{Component, Embed, Mention, MessageFlags, MessageSticker, MessageType};
use crate::id::marker::RoleMarker;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct MessageSnapshot {
pub message: MessageSnapshotFields,
#[serde(skip_serializing_if = "Option::is_none")]
pub guild_id: Option<Id<GuildMarker>>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct MessageSnapshotFields {
pub attachments: Vec<Attachment>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub components: Vec<Component>,
pub content: String,
pub edited_timestamp: Option<Timestamp>,
pub embeds: Vec<Embed>,
#[serde(skip_serializing_if = "Option::is_none")]
pub flags: Option<MessageFlags>,
#[serde(rename = "type")]
pub kind: MessageType,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub mentions: Vec<Mention>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub mention_roles: Vec<Id<RoleMarker>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub sticker_items: Vec<MessageSticker>,
pub timestamp: Timestamp,
}
#[cfg(test)]
mod tests {
use super::{MessageSnapshot, MessageSnapshotFields};
use crate::channel::message::component::{ActionRow, Button, ButtonStyle, ComponentType};
use crate::channel::message::sticker::StickerFormatType;
use crate::channel::message::{Component, MessageSticker, MessageType};
use crate::{channel::Attachment, id::Id, util::Timestamp};
use serde_test::Token;
#[test]
fn test_message_snapshot() {
let value = MessageSnapshot {
message: MessageSnapshotFields {
attachments: vec![Attachment {
content_type: None,
description: None,
duration_secs: None,
ephemeral: false,
filename: "file.jpg".to_owned(),
flags: None,
height: Some(100),
id: Id::new(1),
proxy_url: "https://example.com".to_owned(),
size: 1000,
title: None,
url: "https://example.com".to_owned(),
waveform: None,
width: Some(100),
}],
components: vec![],
content: "test".to_owned(),
edited_timestamp: Some(Timestamp::from_secs(1_571_573_184).unwrap()),
embeds: Vec::new(),
kind: MessageType::Regular,
flags: None,
mentions: Vec::new(),
mention_roles: Vec::new(),
sticker_items: Vec::new(),
timestamp: Timestamp::from_secs(1_571_573_184).unwrap(),
},
guild_id: Some(Id::new(1)),
};
serde_test::assert_tokens(
&value,
&[
Token::Struct {
name: "MessageSnapshot",
len: 2,
},
Token::Str("message"),
Token::Struct {
name: "MessageSnapshotFields",
len: 6,
},
Token::Str("attachments"),
Token::Seq { len: Some(1) },
Token::Struct {
name: "Attachment",
len: 8,
},
Token::Str("content_type"),
Token::None,
Token::Str("filename"),
Token::Str("file.jpg"),
Token::Str("height"),
Token::Some,
Token::U64(100),
Token::Str("id"),
Token::NewtypeStruct { name: "Id" },
Token::Str("1"),
Token::Str("proxy_url"),
Token::Str("https://example.com"),
Token::Str("size"),
Token::U64(1000),
Token::Str("url"),
Token::Str("https://example.com"),
Token::Str("width"),
Token::Some,
Token::U64(100),
Token::StructEnd,
Token::SeqEnd,
Token::Str("content"),
Token::Str("test"),
Token::Str("edited_timestamp"),
Token::Some,
Token::Str("2019-10-20T12:06:24.000000+00:00"),
Token::Str("embeds"),
Token::Seq { len: Some(0) },
Token::SeqEnd,
Token::Str("type"),
Token::U8(0),
Token::Str("timestamp"),
Token::Str("2019-10-20T12:06:24.000000+00:00"),
Token::StructEnd,
Token::Str("guild_id"),
Token::Some,
Token::NewtypeStruct { name: "Id" },
Token::Str("1"),
Token::StructEnd,
],
);
}
#[allow(clippy::too_many_lines)]
#[test]
fn test_message_snapshot_with_sticker_and_components() {
let value = MessageSnapshot {
message: MessageSnapshotFields {
attachments: vec![Attachment {
content_type: None,
description: None,
duration_secs: None,
ephemeral: false,
filename: "file.jpg".to_owned(),
flags: None,
height: Some(100),
id: Id::new(1),
proxy_url: "https://example.com".to_owned(),
size: 1000,
title: None,
url: "https://example.com".to_owned(),
waveform: None,
width: Some(100),
}],
components: vec![Component::ActionRow(ActionRow {
id: None,
components: Vec::from([Component::Button(Button {
id: None,
custom_id: Some("button-1".to_owned()),
disabled: false,
emoji: None,
style: ButtonStyle::Primary,
label: Some("Button".to_owned()),
url: None,
sku_id: None,
})]),
})],
content: "test".to_owned(),
edited_timestamp: Some(Timestamp::from_secs(1_571_573_184).unwrap()),
embeds: Vec::new(),
kind: MessageType::Regular,
flags: None,
mentions: Vec::new(),
mention_roles: Vec::new(),
sticker_items: vec![MessageSticker {
format_type: StickerFormatType::Png,
id: Id::new(1),
name: "sticker name".to_owned(),
}],
timestamp: Timestamp::from_secs(1_571_573_184).unwrap(),
},
guild_id: Some(Id::new(1)),
};
serde_test::assert_tokens(
&value,
&[
Token::Struct {
name: "MessageSnapshot",
len: 2,
},
Token::Str("message"),
Token::Struct {
name: "MessageSnapshotFields",
len: 8,
},
Token::Str("attachments"),
Token::Seq { len: Some(1) },
Token::Struct {
name: "Attachment",
len: 8,
},
Token::Str("content_type"),
Token::None,
Token::Str("filename"),
Token::Str("file.jpg"),
Token::Str("height"),
Token::Some,
Token::U64(100),
Token::Str("id"),
Token::NewtypeStruct { name: "Id" },
Token::Str("1"),
Token::Str("proxy_url"),
Token::Str("https://example.com"),
Token::Str("size"),
Token::U64(1000),
Token::Str("url"),
Token::Str("https://example.com"),
Token::Str("width"),
Token::Some,
Token::U64(100),
Token::StructEnd,
Token::SeqEnd,
Token::String("components"),
Token::Seq { len: Some(1) },
Token::Struct {
name: "Component",
len: 2,
},
Token::String("type"),
Token::U8(ComponentType::ActionRow.into()),
Token::String("components"),
Token::Seq { len: Some(1) },
Token::Struct {
name: "Component",
len: 4,
},
Token::String("type"),
Token::U8(2),
Token::String("custom_id"),
Token::Some,
Token::String("button-1"),
Token::String("label"),
Token::Some,
Token::String("Button"),
Token::String("style"),
Token::U8(1),
Token::StructEnd,
Token::SeqEnd,
Token::StructEnd,
Token::SeqEnd,
Token::Str("content"),
Token::Str("test"),
Token::Str("edited_timestamp"),
Token::Some,
Token::Str("2019-10-20T12:06:24.000000+00:00"),
Token::Str("embeds"),
Token::Seq { len: Some(0) },
Token::SeqEnd,
Token::Str("type"),
Token::U8(0),
Token::Str("sticker_items"),
Token::Seq { len: Some(1) },
Token::Struct {
name: "MessageSticker",
len: 3,
},
Token::Str("format_type"),
Token::U8(1),
Token::Str("id"),
Token::NewtypeStruct { name: "Id" },
Token::Str("1"),
Token::Str("name"),
Token::Str("sticker name"),
Token::StructEnd,
Token::SeqEnd,
Token::Str("timestamp"),
Token::Str("2019-10-20T12:06:24.000000+00:00"),
Token::StructEnd,
Token::Str("guild_id"),
Token::Some,
Token::NewtypeStruct { name: "Id" },
Token::Str("1"),
Token::StructEnd,
],
);
}
}