twilight_model/channel/message/
mod.rs

1//! Textual user communication method.
2#![warn(missing_docs)]
3
4pub mod component;
5pub mod embed;
6pub mod sticker;
7
8mod activity;
9mod allowed_mentions;
10mod application;
11mod call;
12mod flags;
13mod interaction;
14mod kind;
15mod mention;
16mod message_pin;
17mod pins_listing;
18mod reaction;
19mod reaction_type;
20mod reference;
21mod reference_type;
22mod role_subscription_data;
23mod snapshot;
24
25pub use self::{
26    activity::{MessageActivity, MessageActivityType},
27    allowed_mentions::{AllowedMentions, MentionType},
28    application::MessageApplication,
29    call::MessageCall,
30    component::Component,
31    embed::Embed,
32    flags::MessageFlags,
33    interaction::MessageInteraction,
34    kind::MessageType,
35    mention::Mention,
36    message_pin::MessagePin,
37    pins_listing::PinsListing,
38    reaction::{EmojiReactionType, Reaction, ReactionCountDetails},
39    reaction_type::ReactionType,
40    reference::MessageReference,
41    reference_type::MessageReferenceType,
42    role_subscription_data::RoleSubscriptionData,
43    snapshot::MessageSnapshot,
44    sticker::{MessageSticker, Sticker},
45};
46
47use crate::{
48    application::interaction::InteractionMetadata,
49    channel::{Attachment, Channel, ChannelMention},
50    guild::PartialMember,
51    id::{
52        Id,
53        marker::{
54            ApplicationMarker, ChannelMarker, GuildMarker, MessageMarker, RoleMarker, WebhookMarker,
55        },
56    },
57    poll::Poll,
58    user::User,
59    util::Timestamp,
60};
61use serde::{Deserialize, Serialize};
62
63/// Text message sent in a [`Channel`].
64#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
65pub struct Message {
66    /// Present with Rich Presence-related chat embeds.
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub activity: Option<MessageActivity>,
69    /// Present with Rich Presence-related chat embeds.
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub application: Option<MessageApplication>,
72    /// Associated application's ID.
73    ///
74    /// Present if the message is a response to an [`Interaction`].
75    ///
76    /// [`Interaction`]: crate::application::interaction::Interaction
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub application_id: Option<Id<ApplicationMarker>>,
79    /// List of attachments.
80    ///
81    /// Receiving the attachments of messages requires that the
82    /// [Message Content Intent] be enabled for the application. In the case of
83    /// receiving messages over the Gateway, the intent must also be enabled for
84    /// the session.
85    ///
86    /// Message attachments will be empty unless the [Message Content Intent] is
87    /// enabled, the message was sent by the current user, or the message is in
88    /// a direct message channel.
89    ///
90    /// [Message Content Intent]: crate::gateway::Intents::MESSAGE_CONTENT
91    pub attachments: Vec<Attachment>,
92    /// Author of the message.
93    pub author: User,
94    /// The call associated with the message.
95    pub call: Option<MessageCall>,
96    /// ID of the [`Channel`] the message was sent in.
97    pub channel_id: Id<ChannelMarker>,
98    /// List of provided components, such as buttons.
99    ///
100    /// Receiving the components of messages requires that the
101    /// [Message Content Intent] be enabled for the application. In the case of
102    /// receiving messages over the Gateway, the intent must also be enabled for
103    /// the session.
104    ///
105    /// Message components will be empty unless the [Message Content Intent] is
106    /// enabled, the message was sent by the current user, or the message is in
107    /// a direct message channel.
108    ///
109    /// [Message Content Intent]: crate::gateway::Intents::MESSAGE_CONTENT
110    #[serde(default, skip_serializing_if = "Vec::is_empty")]
111    pub components: Vec<Component>,
112    /// Content of the message.
113    ///
114    /// Receiving the content of messages requires that the
115    /// [Message Content Intent] be enabled for the application. In the case of
116    /// receiving messages over the Gateway, the intent must also be enabled for
117    /// the session.
118    ///
119    /// Message content will be empty unless the [Message Content Intent] is
120    /// enabled, the message was sent by the current user, or the message is in
121    /// a direct message channel.
122    ///
123    /// [Message Content Intent]: crate::gateway::Intents::MESSAGE_CONTENT
124    pub content: String,
125    /// When the message was last edited.
126    pub edited_timestamp: Option<Timestamp>,
127    /// List of embeds.
128    ///
129    /// Receiving the embeds of messages requires that the
130    /// [Message Content Intent] be enabled for the application. In the case of
131    /// receiving messages over the Gateway, the intent must also be enabled for
132    /// the session.
133    ///
134    /// Message embeds will be empty unless the [Message Content Intent] is
135    /// enabled, the message was sent by the current user, or the message is in
136    /// a direct message channel.
137    ///
138    /// [Message Content Intent]: crate::gateway::Intents::MESSAGE_CONTENT
139    pub embeds: Vec<Embed>,
140    /// Flags of the message.
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub flags: Option<MessageFlags>,
143    /// ID of the [`Guild`] the message was sent in.
144    ///
145    /// [`Guild`]: crate::guild::Guild
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub guild_id: Option<Id<GuildMarker>>,
148    /// Id of the message.
149    pub id: Id<MessageMarker>,
150    /// Interaction the message was sent as a response to.
151    #[deprecated(note = "use interaction_metadata instead")]
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub interaction: Option<MessageInteraction>,
154    /// Contains metadata related to the interacting if the message is
155    /// sent as a result of an interaction.
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub interaction_metadata: Option<Box<InteractionMetadata>>,
158    /// Type of message.
159    #[serde(rename = "type")]
160    pub kind: MessageType,
161    /// Member properties of the [`author`].
162    ///
163    /// [`author`]: Message::author
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub member: Option<PartialMember>,
166    /// [`Channel`]s mentioned in the message.
167    ///
168    /// Note: only textual channels visible to everyone mentioned in crossposted
169    /// messages (via channel following) will be included.
170    #[serde(default, skip_serializing_if = "Vec::is_empty")]
171    pub mention_channels: Vec<ChannelMention>,
172    /// Whether the message mentions `@everyone`.
173    pub mention_everyone: bool,
174    /// [`Role`]s mentioned in the message.
175    ///
176    /// [`Role`]: crate::guild::Role
177    pub mention_roles: Vec<Id<RoleMarker>>,
178    /// Users mentioned in the message.
179    pub mentions: Vec<Mention>,
180    /// The message associated with the [`MessageReference`]. This is a minimal subset
181    /// of fields in a message (e.g. author is excluded.).
182    #[serde(default, skip_serializing_if = "Vec::is_empty")]
183    pub message_snapshots: Vec<MessageSnapshot>,
184    /// Whether the message is pinned.
185    pub pinned: bool,
186    /// The poll associated with the message.
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub poll: Option<Poll>,
189    /// List of reactions to the message.
190    #[serde(default, skip_serializing_if = "Vec::is_empty")]
191    pub reactions: Vec<Reaction>,
192    /// Crosspost, channel follow add, pin and reply source message data.
193    #[serde(rename = "message_reference", skip_serializing_if = "Option::is_none")]
194    pub reference: Option<MessageReference>,
195    /// The message associated with the [`reference`].
196    ///
197    /// [`reference`]: Self::reference
198    #[serde(skip_serializing_if = "Option::is_none")]
199    pub referenced_message: Option<Box<Message>>,
200    /// Information about the role subscription purchase or renewal that
201    /// prompted this message.
202    ///
203    /// Applies to [`RoleSubscriptionPurchase`] messages.
204    ///
205    /// [`RoleSubscriptionPurchase`]: MessageType::RoleSubscriptionPurchase
206    #[serde(skip_serializing_if = "Option::is_none")]
207    pub role_subscription_data: Option<RoleSubscriptionData>,
208    /// Stickers within the message.
209    #[serde(default)]
210    pub sticker_items: Vec<MessageSticker>,
211    /// Timestamp of when the message was created.
212    pub timestamp: Timestamp,
213    /// Thread started from this message, includes [`Channel::member`].
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub thread: Option<Channel>,
216    /// Whether the message was a TTS message.
217    pub tts: bool,
218    /// ID of the webhook that generated the message.
219    #[serde(skip_serializing_if = "Option::is_none")]
220    pub webhook_id: Option<Id<WebhookMarker>>,
221}
222
223#[cfg(test)]
224mod tests {
225    use super::{
226        EmojiReactionType, Message, MessageActivity, MessageActivityType, MessageApplication,
227        MessageCall, MessageFlags, MessageReference, MessageType, Reaction,
228        reaction::ReactionCountDetails,
229        reference_type::MessageReferenceType,
230        sticker::{MessageSticker, StickerFormatType},
231    };
232    use crate::{
233        channel::{ChannelMention, ChannelType},
234        guild::{MemberFlags, PartialMember},
235        id::Id,
236        test::image_hash,
237        user::User,
238        util::{Timestamp, datetime::TimestampParseError},
239    };
240    use serde_test::Token;
241    use std::str::FromStr;
242
243    #[allow(clippy::too_many_lines, deprecated)]
244    #[test]
245    fn message_deserialization() {
246        let joined_at = Some(Timestamp::from_str("2020-01-01T00:00:00.000000+00:00").unwrap());
247        let timestamp = Timestamp::from_micros(1_580_608_922_020_000).expect("non zero");
248        let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
249
250        let value = Message {
251            activity: None,
252            application: None,
253            application_id: None,
254            attachments: Vec::new(),
255            author: User {
256                accent_color: None,
257                avatar: Some(image_hash::AVATAR),
258                avatar_decoration: None,
259                avatar_decoration_data: None,
260                banner: None,
261                bot: false,
262                discriminator: 1,
263                email: None,
264                flags: None,
265                global_name: Some("test".to_owned()),
266                id: Id::new(3),
267                locale: None,
268                mfa_enabled: None,
269                name: "test".to_owned(),
270                premium_type: None,
271                primary_guild: None,
272                public_flags: None,
273                system: None,
274                verified: None,
275            },
276            call: Some(MessageCall {
277                ended_timestamp: None,
278                participants: Vec::new(),
279            }),
280            channel_id: Id::new(2),
281            components: Vec::new(),
282            content: "ping".to_owned(),
283            edited_timestamp: None,
284            embeds: Vec::new(),
285            flags: Some(MessageFlags::empty()),
286            guild_id: Some(Id::new(1)),
287            id: Id::new(4),
288            interaction: None,
289            kind: MessageType::Regular,
290            member: Some(PartialMember {
291                avatar: None,
292                avatar_decoration_data: None,
293                banner: None,
294                communication_disabled_until: None,
295                deaf: false,
296                flags,
297                joined_at,
298                mute: false,
299                nick: Some("member nick".to_owned()),
300                permissions: None,
301                premium_since: None,
302                roles: Vec::new(),
303                user: None,
304            }),
305            mention_channels: Vec::new(),
306            mention_everyone: false,
307            mention_roles: Vec::new(),
308            mentions: Vec::new(),
309            message_snapshots: Vec::new(),
310            pinned: false,
311            poll: None,
312            reactions: Vec::new(),
313            reference: None,
314            role_subscription_data: None,
315            sticker_items: vec![MessageSticker {
316                format_type: StickerFormatType::Png,
317                id: Id::new(1),
318                name: "sticker name".to_owned(),
319            }],
320            referenced_message: None,
321            timestamp,
322            thread: None,
323            tts: false,
324            webhook_id: None,
325            interaction_metadata: None,
326        };
327
328        serde_test::assert_tokens(
329            &value,
330            &[
331                Token::Struct {
332                    name: "Message",
333                    len: 19,
334                },
335                Token::Str("attachments"),
336                Token::Seq { len: Some(0) },
337                Token::SeqEnd,
338                Token::Str("author"),
339                Token::Struct {
340                    name: "User",
341                    len: 10,
342                },
343                Token::Str("accent_color"),
344                Token::None,
345                Token::Str("avatar"),
346                Token::Some,
347                Token::Str(image_hash::AVATAR_INPUT),
348                Token::Str("avatar_decoration"),
349                Token::None,
350                Token::Str("avatar_decoration_data"),
351                Token::None,
352                Token::Str("banner"),
353                Token::None,
354                Token::Str("bot"),
355                Token::Bool(false),
356                Token::Str("discriminator"),
357                Token::Str("0001"),
358                Token::Str("global_name"),
359                Token::Some,
360                Token::Str("test"),
361                Token::Str("id"),
362                Token::NewtypeStruct { name: "Id" },
363                Token::Str("3"),
364                Token::Str("username"),
365                Token::Str("test"),
366                Token::StructEnd,
367                Token::Str("call"),
368                Token::Some,
369                Token::Struct {
370                    name: "MessageCall",
371                    len: 2,
372                },
373                Token::Str("ended_timestamp"),
374                Token::None,
375                Token::Str("participants"),
376                Token::Seq { len: Some(0) },
377                Token::SeqEnd,
378                Token::StructEnd,
379                Token::Str("channel_id"),
380                Token::NewtypeStruct { name: "Id" },
381                Token::Str("2"),
382                Token::Str("content"),
383                Token::Str("ping"),
384                Token::Str("edited_timestamp"),
385                Token::None,
386                Token::Str("embeds"),
387                Token::Seq { len: Some(0) },
388                Token::SeqEnd,
389                Token::Str("flags"),
390                Token::Some,
391                Token::U64(0),
392                Token::Str("guild_id"),
393                Token::Some,
394                Token::NewtypeStruct { name: "Id" },
395                Token::Str("1"),
396                Token::Str("id"),
397                Token::NewtypeStruct { name: "Id" },
398                Token::Str("4"),
399                Token::Str("type"),
400                Token::U8(0),
401                Token::Str("member"),
402                Token::Some,
403                Token::Struct {
404                    name: "PartialMember",
405                    len: 8,
406                },
407                Token::Str("communication_disabled_until"),
408                Token::None,
409                Token::Str("deaf"),
410                Token::Bool(false),
411                Token::Str("flags"),
412                Token::U64(flags.bits()),
413                Token::Str("joined_at"),
414                Token::Some,
415                Token::Str("2020-01-01T00:00:00.000000+00:00"),
416                Token::Str("mute"),
417                Token::Bool(false),
418                Token::Str("nick"),
419                Token::Some,
420                Token::Str("member nick"),
421                Token::Str("roles"),
422                Token::Seq { len: Some(0) },
423                Token::SeqEnd,
424                Token::Str("user"),
425                Token::None,
426                Token::StructEnd,
427                Token::Str("mention_everyone"),
428                Token::Bool(false),
429                Token::Str("mention_roles"),
430                Token::Seq { len: Some(0) },
431                Token::SeqEnd,
432                Token::Str("mentions"),
433                Token::Seq { len: Some(0) },
434                Token::SeqEnd,
435                Token::Str("pinned"),
436                Token::Bool(false),
437                Token::Str("sticker_items"),
438                Token::Seq { len: Some(1) },
439                Token::Struct {
440                    name: "MessageSticker",
441                    len: 3,
442                },
443                Token::Str("format_type"),
444                Token::U8(1),
445                Token::Str("id"),
446                Token::NewtypeStruct { name: "Id" },
447                Token::Str("1"),
448                Token::Str("name"),
449                Token::Str("sticker name"),
450                Token::StructEnd,
451                Token::SeqEnd,
452                Token::Str("timestamp"),
453                Token::Str("2020-02-02T02:02:02.020000+00:00"),
454                Token::Str("tts"),
455                Token::Bool(false),
456                Token::StructEnd,
457            ],
458        );
459    }
460
461    #[allow(clippy::too_many_lines, deprecated)]
462    #[test]
463    fn message_deserialization_complete() -> Result<(), TimestampParseError> {
464        let edited_timestamp = Timestamp::from_str("2021-08-10T12:41:51.602000+00:00")?;
465        let joined_at = Some(Timestamp::from_str("2020-01-01T00:00:00.000000+00:00")?);
466        let timestamp = Timestamp::from_micros(1_580_608_922_020_000).expect("non zero");
467        let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
468
469        let value = Message {
470            activity: Some(MessageActivity {
471                kind: MessageActivityType::Join,
472                party_id: None,
473            }),
474            application: Some(MessageApplication {
475                cover_image: Some(image_hash::COVER),
476                description: "a description".to_owned(),
477                icon: Some(image_hash::ICON),
478                id: Id::new(1),
479                name: "application".to_owned(),
480            }),
481            application_id: Some(Id::new(1)),
482            attachments: Vec::new(),
483            author: User {
484                accent_color: None,
485                avatar: Some(image_hash::AVATAR),
486                avatar_decoration: None,
487                avatar_decoration_data: None,
488                banner: None,
489                bot: false,
490                discriminator: 1,
491                email: None,
492                flags: None,
493                global_name: Some("test".to_owned()),
494                id: Id::new(3),
495                locale: None,
496                mfa_enabled: None,
497                name: "test".to_owned(),
498                premium_type: None,
499                primary_guild: None,
500                public_flags: None,
501                system: None,
502                verified: None,
503            },
504            call: None,
505            channel_id: Id::new(2),
506            components: Vec::new(),
507            content: "ping".to_owned(),
508            edited_timestamp: Some(edited_timestamp),
509            embeds: Vec::new(),
510            flags: Some(MessageFlags::empty()),
511            guild_id: Some(Id::new(1)),
512            id: Id::new(4),
513            interaction: None,
514            kind: MessageType::Regular,
515            member: Some(PartialMember {
516                avatar: None,
517                avatar_decoration_data: None,
518                banner: None,
519                communication_disabled_until: None,
520                deaf: false,
521                flags,
522                joined_at,
523                mute: false,
524                nick: Some("member nick".to_owned()),
525                permissions: None,
526                premium_since: None,
527                roles: Vec::new(),
528                user: None,
529            }),
530            mention_channels: vec![ChannelMention {
531                guild_id: Id::new(1),
532                id: Id::new(2),
533                kind: ChannelType::GuildText,
534                name: "channel".to_owned(),
535            }],
536            mention_everyone: false,
537            mention_roles: Vec::new(),
538            mentions: Vec::new(),
539            message_snapshots: Vec::new(),
540            pinned: false,
541            poll: None,
542            reactions: vec![Reaction {
543                burst_colors: Vec::new(),
544                count: 7,
545                count_details: ReactionCountDetails {
546                    burst: 0,
547                    normal: 7,
548                },
549                emoji: EmojiReactionType::Unicode {
550                    name: "a".to_owned(),
551                },
552                me: true,
553                me_burst: false,
554            }],
555            reference: Some(MessageReference {
556                channel_id: Some(Id::new(1)),
557                guild_id: None,
558                kind: MessageReferenceType::Default,
559                message_id: None,
560                fail_if_not_exists: None,
561            }),
562            role_subscription_data: None,
563            sticker_items: vec![MessageSticker {
564                format_type: StickerFormatType::Png,
565                id: Id::new(1),
566                name: "sticker name".to_owned(),
567            }],
568            referenced_message: None,
569            timestamp,
570            thread: None,
571            tts: false,
572            webhook_id: Some(Id::new(1)),
573            interaction_metadata: None,
574        };
575
576        serde_test::assert_tokens(
577            &value,
578            &[
579                Token::Struct {
580                    name: "Message",
581                    len: 26,
582                },
583                Token::Str("activity"),
584                Token::Some,
585                Token::Struct {
586                    name: "MessageActivity",
587                    len: 1,
588                },
589                Token::Str("type"),
590                Token::U8(1),
591                Token::StructEnd,
592                Token::Str("application"),
593                Token::Some,
594                Token::Struct {
595                    name: "MessageApplication",
596                    len: 5,
597                },
598                Token::Str("cover_image"),
599                Token::Some,
600                Token::Str(image_hash::COVER_INPUT),
601                Token::Str("description"),
602                Token::Str("a description"),
603                Token::Str("icon"),
604                Token::Some,
605                Token::Str(image_hash::ICON_INPUT),
606                Token::Str("id"),
607                Token::NewtypeStruct { name: "Id" },
608                Token::Str("1"),
609                Token::Str("name"),
610                Token::Str("application"),
611                Token::StructEnd,
612                Token::Str("application_id"),
613                Token::Some,
614                Token::NewtypeStruct { name: "Id" },
615                Token::Str("1"),
616                Token::Str("attachments"),
617                Token::Seq { len: Some(0) },
618                Token::SeqEnd,
619                Token::Str("author"),
620                Token::Struct {
621                    name: "User",
622                    len: 10,
623                },
624                Token::Str("accent_color"),
625                Token::None,
626                Token::Str("avatar"),
627                Token::Some,
628                Token::Str(image_hash::AVATAR_INPUT),
629                Token::Str("avatar_decoration"),
630                Token::None,
631                Token::Str("avatar_decoration_data"),
632                Token::None,
633                Token::Str("banner"),
634                Token::None,
635                Token::Str("bot"),
636                Token::Bool(false),
637                Token::Str("discriminator"),
638                Token::Str("0001"),
639                Token::Str("global_name"),
640                Token::Some,
641                Token::Str("test"),
642                Token::Str("id"),
643                Token::NewtypeStruct { name: "Id" },
644                Token::Str("3"),
645                Token::Str("username"),
646                Token::Str("test"),
647                Token::StructEnd,
648                Token::Str("call"),
649                Token::None,
650                Token::Str("channel_id"),
651                Token::NewtypeStruct { name: "Id" },
652                Token::Str("2"),
653                Token::Str("content"),
654                Token::Str("ping"),
655                Token::Str("edited_timestamp"),
656                Token::Some,
657                Token::Str("2021-08-10T12:41:51.602000+00:00"),
658                Token::Str("embeds"),
659                Token::Seq { len: Some(0) },
660                Token::SeqEnd,
661                Token::Str("flags"),
662                Token::Some,
663                Token::U64(0),
664                Token::Str("guild_id"),
665                Token::Some,
666                Token::NewtypeStruct { name: "Id" },
667                Token::Str("1"),
668                Token::Str("id"),
669                Token::NewtypeStruct { name: "Id" },
670                Token::Str("4"),
671                Token::Str("type"),
672                Token::U8(0),
673                Token::Str("member"),
674                Token::Some,
675                Token::Struct {
676                    name: "PartialMember",
677                    len: 8,
678                },
679                Token::Str("communication_disabled_until"),
680                Token::None,
681                Token::Str("deaf"),
682                Token::Bool(false),
683                Token::Str("flags"),
684                Token::U64(flags.bits()),
685                Token::Str("joined_at"),
686                Token::Some,
687                Token::Str("2020-01-01T00:00:00.000000+00:00"),
688                Token::Str("mute"),
689                Token::Bool(false),
690                Token::Str("nick"),
691                Token::Some,
692                Token::Str("member nick"),
693                Token::Str("roles"),
694                Token::Seq { len: Some(0) },
695                Token::SeqEnd,
696                Token::Str("user"),
697                Token::None,
698                Token::StructEnd,
699                Token::Str("mention_channels"),
700                Token::Seq { len: Some(1) },
701                Token::Struct {
702                    name: "ChannelMention",
703                    len: 4,
704                },
705                Token::Str("guild_id"),
706                Token::NewtypeStruct { name: "Id" },
707                Token::Str("1"),
708                Token::Str("id"),
709                Token::NewtypeStruct { name: "Id" },
710                Token::Str("2"),
711                Token::Str("type"),
712                Token::U8(0),
713                Token::Str("name"),
714                Token::Str("channel"),
715                Token::StructEnd,
716                Token::SeqEnd,
717                Token::Str("mention_everyone"),
718                Token::Bool(false),
719                Token::Str("mention_roles"),
720                Token::Seq { len: Some(0) },
721                Token::SeqEnd,
722                Token::Str("mentions"),
723                Token::Seq { len: Some(0) },
724                Token::SeqEnd,
725                Token::Str("pinned"),
726                Token::Bool(false),
727                Token::Str("reactions"),
728                Token::Seq { len: Some(1) },
729                Token::Struct {
730                    name: "Reaction",
731                    len: 6,
732                },
733                Token::Str("burst_colors"),
734                Token::Seq { len: Some(0) },
735                Token::SeqEnd,
736                Token::Str("count"),
737                Token::U64(7),
738                Token::Str("count_details"),
739                Token::Struct {
740                    name: "ReactionCountDetails",
741                    len: 2,
742                },
743                Token::Str("burst"),
744                Token::U64(0),
745                Token::Str("normal"),
746                Token::U64(7),
747                Token::StructEnd,
748                Token::Str("emoji"),
749                Token::Struct {
750                    name: "EmojiReactionType",
751                    len: 1,
752                },
753                Token::Str("name"),
754                Token::Str("a"),
755                Token::StructEnd,
756                Token::Str("me"),
757                Token::Bool(true),
758                Token::Str("me_burst"),
759                Token::Bool(false),
760                Token::StructEnd,
761                Token::SeqEnd,
762                Token::Str("message_reference"),
763                Token::Some,
764                Token::Struct {
765                    name: "MessageReference",
766                    len: 2,
767                },
768                Token::Str("channel_id"),
769                Token::Some,
770                Token::NewtypeStruct { name: "Id" },
771                Token::Str("1"),
772                Token::Str("type"),
773                Token::U8(0),
774                Token::StructEnd,
775                Token::Str("sticker_items"),
776                Token::Seq { len: Some(1) },
777                Token::Struct {
778                    name: "MessageSticker",
779                    len: 3,
780                },
781                Token::Str("format_type"),
782                Token::U8(1),
783                Token::Str("id"),
784                Token::NewtypeStruct { name: "Id" },
785                Token::Str("1"),
786                Token::Str("name"),
787                Token::Str("sticker name"),
788                Token::StructEnd,
789                Token::SeqEnd,
790                Token::Str("timestamp"),
791                Token::Str("2020-02-02T02:02:02.020000+00:00"),
792                Token::Str("tts"),
793                Token::Bool(false),
794                Token::Str("webhook_id"),
795                Token::Some,
796                Token::NewtypeStruct { name: "Id" },
797                Token::Str("1"),
798                Token::StructEnd,
799            ],
800        );
801
802        Ok(())
803    }
804}