1pub mod application_command;
8pub mod callback;
9pub mod message_component;
10pub mod modal;
11
12mod context_type;
13mod interaction_type;
14mod metadata;
15mod resolved;
16
17pub use self::{
18 context_type::InteractionContextType,
19 interaction_type::InteractionType,
20 metadata::InteractionMetadata,
21 resolved::{InteractionChannel, InteractionDataResolved, InteractionMember},
22};
23
24use self::{
25 application_command::CommandData, message_component::MessageComponentInteractionData,
26 modal::ModalInteractionData,
27};
28use crate::{
29 channel::{Channel, Message},
30 guild::{GuildFeature, PartialMember, Permissions},
31 id::{
32 AnonymizableId, Id,
33 marker::{ApplicationMarker, ChannelMarker, GuildMarker, InteractionMarker, UserMarker},
34 },
35 oauth::ApplicationIntegrationMap,
36 user::User,
37};
38use serde::{
39 Deserialize, Deserializer, Serialize,
40 de::{Error as DeError, IgnoredAny, MapAccess, Visitor},
41};
42use serde_value::{DeserializerError, Value};
43use std::fmt::{Formatter, Result as FmtResult};
44
45use super::monetization::Entitlement;
46
47#[derive(Clone, Debug, PartialEq, Serialize)]
53pub struct Interaction {
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub app_permissions: Option<Permissions>,
57 pub application_id: Id<ApplicationMarker>,
59 pub attachment_size_limit: u64,
64 pub authorizing_integration_owners:
67 ApplicationIntegrationMap<AnonymizableId<GuildMarker>, Id<UserMarker>>,
68 #[serde(skip_serializing_if = "Option::is_none")]
74 pub channel: Option<Channel>,
75 #[serde(skip_serializing_if = "Option::is_none")]
81 #[deprecated(
82 note = "channel_id is deprecated in the discord API and will no be sent in the future, users should use the channel field instead."
83 )]
84 pub channel_id: Option<Id<ChannelMarker>>,
85 #[serde(skip_serializing_if = "Option::is_none")]
87 pub context: Option<InteractionContextType>,
88 #[serde(skip_serializing_if = "Option::is_none")]
99 pub data: Option<InteractionData>,
100 pub entitlements: Vec<Entitlement>,
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub guild: Option<InteractionPartialGuild>,
105 #[serde(skip_serializing_if = "Option::is_none")]
107 pub guild_id: Option<Id<GuildMarker>>,
108 #[serde(skip_serializing_if = "Option::is_none")]
112 pub guild_locale: Option<String>,
113 pub id: Id<InteractionMarker>,
115 #[serde(rename = "type")]
117 pub kind: InteractionType,
118 #[serde(skip_serializing_if = "Option::is_none")]
124 pub locale: Option<String>,
125 #[serde(skip_serializing_if = "Option::is_none")]
129 pub member: Option<PartialMember>,
130 #[serde(skip_serializing_if = "Option::is_none")]
136 pub message: Option<Message>,
137 pub token: String,
139 #[serde(skip_serializing_if = "Option::is_none")]
143 pub user: Option<User>,
144}
145
146impl Interaction {
147 pub const fn author_id(&self) -> Option<Id<UserMarker>> {
156 if let Some(user) = self.author() {
157 Some(user.id)
158 } else {
159 None
160 }
161 }
162
163 pub const fn author(&self) -> Option<&User> {
172 match self.member.as_ref() {
173 Some(member) if member.user.is_some() => member.user.as_ref(),
174 _ => self.user.as_ref(),
175 }
176 }
177
178 pub fn into_author(self) -> Option<User> {
187 match self.member {
188 Some(member) if member.user.is_some() => member.user,
189 _ => self.user,
190 }
191 }
192
193 pub const fn is_dm(&self) -> bool {
195 self.user.is_some()
196 }
197
198 pub const fn is_guild(&self) -> bool {
200 self.member.is_some()
201 }
202}
203
204impl<'de> Deserialize<'de> for Interaction {
205 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
206 deserializer.deserialize_map(InteractionVisitor)
207 }
208}
209
210#[derive(Debug, Deserialize)]
211#[serde(field_identifier, rename_all = "snake_case")]
212enum InteractionField {
213 AppPermissions,
214 ApplicationId,
215 Context,
216 Channel,
217 ChannelId,
218 Data,
219 Entitlements,
220 Guild,
221 GuildId,
222 GuildLocale,
223 Id,
224 Locale,
225 Member,
226 Message,
227 Token,
228 Type,
229 User,
230 Version,
231 AuthorizingIntegrationOwners,
232 AttachmentSizeLimit,
233}
234
235struct InteractionVisitor;
236
237impl<'de> Visitor<'de> for InteractionVisitor {
238 type Value = Interaction;
239
240 fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
241 f.write_str("enum Interaction")
242 }
243
244 #[allow(clippy::too_many_lines, deprecated)]
245 fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
246 let mut app_permissions: Option<Permissions> = None;
247 let mut application_id: Option<Id<ApplicationMarker>> = None;
248 let mut channel: Option<Channel> = None;
249 let mut channel_id: Option<Id<ChannelMarker>> = None;
250 let mut context: Option<InteractionContextType> = None;
251 let mut data: Option<Value> = None;
252 let mut entitlements: Option<Vec<Entitlement>> = None;
253 let mut guild: Option<InteractionPartialGuild> = None;
254 let mut guild_id: Option<Id<GuildMarker>> = None;
255 let mut guild_locale: Option<String> = None;
256 let mut id: Option<Id<InteractionMarker>> = None;
257 let mut kind: Option<InteractionType> = None;
258 let mut locale: Option<String> = None;
259 let mut member: Option<PartialMember> = None;
260 let mut message: Option<Message> = None;
261 let mut token: Option<String> = None;
262 let mut user: Option<User> = None;
263 let mut authorizing_integration_owners: Option<
264 ApplicationIntegrationMap<AnonymizableId<GuildMarker>, Id<UserMarker>>,
265 > = None;
266 let mut attachment_size_limit: Option<u64> = None;
267
268 loop {
269 let key = match map.next_key() {
270 Ok(Some(key)) => key,
271 Ok(None) => break,
272 Err(_) => {
273 map.next_value::<IgnoredAny>()?;
274
275 continue;
276 }
277 };
278
279 match key {
280 InteractionField::AppPermissions => {
281 if app_permissions.is_some() {
282 return Err(DeError::duplicate_field("app_permissions"));
283 }
284
285 app_permissions = map.next_value()?;
286 }
287 InteractionField::ApplicationId => {
288 if application_id.is_some() {
289 return Err(DeError::duplicate_field("application_id"));
290 }
291
292 application_id = Some(map.next_value()?);
293 }
294 InteractionField::Context => {
295 if context.is_some() {
296 return Err(DeError::duplicate_field("context"));
297 }
298
299 context = map.next_value()?;
300 }
301 InteractionField::Channel => {
302 if channel.is_some() {
303 return Err(DeError::duplicate_field("channel"));
304 }
305
306 channel = map.next_value()?;
307 }
308 InteractionField::ChannelId => {
309 if channel_id.is_some() {
310 return Err(DeError::duplicate_field("channel_id"));
311 }
312
313 channel_id = map.next_value()?;
314 }
315 InteractionField::Data => {
316 if data.is_some() {
317 return Err(DeError::duplicate_field("data"));
318 }
319
320 data = map.next_value()?;
321 }
322 InteractionField::Entitlements => {
323 if entitlements.is_some() {
324 return Err(DeError::duplicate_field("entitlements"));
325 }
326
327 entitlements = map.next_value()?;
328 }
329 InteractionField::Guild => {
330 if guild.is_some() {
331 return Err(DeError::duplicate_field("guild"));
332 }
333
334 guild = map.next_value()?;
335 }
336 InteractionField::GuildId => {
337 if guild_id.is_some() {
338 return Err(DeError::duplicate_field("guild_id"));
339 }
340
341 guild_id = map.next_value()?;
342 }
343 InteractionField::GuildLocale => {
344 if guild_locale.is_some() {
345 return Err(DeError::duplicate_field("guild_locale"));
346 }
347
348 guild_locale = map.next_value()?;
349 }
350 InteractionField::Id => {
351 if id.is_some() {
352 return Err(DeError::duplicate_field("id"));
353 }
354
355 id = Some(map.next_value()?);
356 }
357 InteractionField::Locale => {
358 if locale.is_some() {
359 return Err(DeError::duplicate_field("locale"));
360 }
361
362 locale = map.next_value()?;
363 }
364 InteractionField::Member => {
365 if member.is_some() {
366 return Err(DeError::duplicate_field("member"));
367 }
368
369 member = map.next_value()?;
370 }
371 InteractionField::Message => {
372 if message.is_some() {
373 return Err(DeError::duplicate_field("message"));
374 }
375
376 message = map.next_value()?;
377 }
378 InteractionField::Token => {
379 if token.is_some() {
380 return Err(DeError::duplicate_field("token"));
381 }
382
383 token = Some(map.next_value()?);
384 }
385 InteractionField::Type => {
386 if kind.is_some() {
387 return Err(DeError::duplicate_field("kind"));
388 }
389
390 kind = Some(map.next_value()?);
391 }
392 InteractionField::User => {
393 if user.is_some() {
394 return Err(DeError::duplicate_field("user"));
395 }
396
397 user = map.next_value()?;
398 }
399 InteractionField::Version => {
400 map.next_value::<IgnoredAny>()?;
402 }
403 InteractionField::AuthorizingIntegrationOwners => {
404 if authorizing_integration_owners.is_some() {
405 return Err(DeError::duplicate_field("authorizing_integration_owners"));
406 }
407
408 authorizing_integration_owners = map.next_value()?;
409 }
410 InteractionField::AttachmentSizeLimit => {
411 if attachment_size_limit.is_some() {
412 return Err(DeError::duplicate_field("attachment_size_limit"));
413 }
414
415 attachment_size_limit = map.next_value()?;
416 }
417 }
418 }
419
420 let application_id =
421 application_id.ok_or_else(|| DeError::missing_field("application_id"))?;
422 let attachment_size_limit =
423 attachment_size_limit.ok_or_else(|| DeError::missing_field("attachment_size_limit"))?;
424 let authorizing_integration_owners = authorizing_integration_owners
425 .ok_or_else(|| DeError::missing_field("authorizing_integration_owners"))?;
426 let id = id.ok_or_else(|| DeError::missing_field("id"))?;
427 let token = token.ok_or_else(|| DeError::missing_field("token"))?;
428 let kind = kind.ok_or_else(|| DeError::missing_field("kind"))?;
429
430 let data = match kind {
431 InteractionType::Ping => None,
432 InteractionType::ApplicationCommand => {
433 let data = data
434 .ok_or_else(|| DeError::missing_field("data"))?
435 .deserialize_into()
436 .map_err(DeserializerError::into_error)?;
437
438 Some(InteractionData::ApplicationCommand(data))
439 }
440 InteractionType::MessageComponent => {
441 let data = data
442 .ok_or_else(|| DeError::missing_field("data"))?
443 .deserialize_into()
444 .map_err(DeserializerError::into_error)?;
445
446 Some(InteractionData::MessageComponent(data))
447 }
448 InteractionType::ApplicationCommandAutocomplete => {
449 let data = data
450 .ok_or_else(|| DeError::missing_field("data"))?
451 .deserialize_into()
452 .map_err(DeserializerError::into_error)?;
453
454 Some(InteractionData::ApplicationCommand(data))
455 }
456 InteractionType::ModalSubmit => {
457 let data = data
458 .ok_or_else(|| DeError::missing_field("data"))?
459 .deserialize_into()
460 .map_err(DeserializerError::into_error)?;
461
462 Some(InteractionData::ModalSubmit(data))
463 }
464 };
465
466 let entitlements = entitlements.unwrap_or_default();
467
468 Ok(Self::Value {
469 app_permissions,
470 application_id,
471 attachment_size_limit,
472 authorizing_integration_owners,
473 channel,
474 channel_id,
475 context,
476 data,
477 entitlements,
478 guild,
479 guild_id,
480 guild_locale,
481 id,
482 kind,
483 locale,
484 member,
485 message,
486 token,
487 user,
488 })
489 }
490}
491
492#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
494#[non_exhaustive]
495#[serde(untagged)]
496pub enum InteractionData {
497 ApplicationCommand(Box<CommandData>),
503 MessageComponent(Box<MessageComponentInteractionData>),
507 ModalSubmit(Box<ModalInteractionData>),
511}
512
513impl From<Box<CommandData>> for InteractionData {
514 fn from(value: Box<CommandData>) -> Self {
515 InteractionData::ApplicationCommand(value)
516 }
517}
518
519impl From<Box<MessageComponentInteractionData>> for InteractionData {
520 fn from(value: Box<MessageComponentInteractionData>) -> Self {
521 InteractionData::MessageComponent(value)
522 }
523}
524
525impl From<Box<ModalInteractionData>> for InteractionData {
526 fn from(value: Box<ModalInteractionData>) -> Self {
527 InteractionData::ModalSubmit(value)
528 }
529}
530
531impl TryFrom<InteractionData> for Box<CommandData> {
532 type Error = InteractionData;
533
534 fn try_from(value: InteractionData) -> Result<Self, Self::Error> {
535 match value {
536 InteractionData::ApplicationCommand(inner) => Ok(inner),
537 _ => Err(value),
538 }
539 }
540}
541
542impl TryFrom<InteractionData> for Box<MessageComponentInteractionData> {
543 type Error = InteractionData;
544
545 fn try_from(value: InteractionData) -> Result<Self, Self::Error> {
546 match value {
547 InteractionData::MessageComponent(inner) => Ok(inner),
548 _ => Err(value),
549 }
550 }
551}
552
553impl TryFrom<InteractionData> for Box<ModalInteractionData> {
554 type Error = InteractionData;
555
556 fn try_from(value: InteractionData) -> Result<Self, Self::Error> {
557 match value {
558 InteractionData::ModalSubmit(inner) => Ok(inner),
559 _ => Err(value),
560 }
561 }
562}
563
564#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize, Hash)]
572pub struct InteractionPartialGuild {
573 pub features: Option<Vec<GuildFeature>>,
575 pub id: Option<Id<GuildMarker>>,
577 pub locale: Option<String>,
578}
579
580#[cfg(test)]
581mod tests {
582 use super::{
583 Interaction, InteractionData, InteractionDataResolved, InteractionMember, InteractionType,
584 application_command::{CommandData, CommandDataOption, CommandOptionValue},
585 };
586 use crate::{
587 application::{
588 command::{CommandOptionType, CommandType},
589 monetization::{EntitlementType, entitlement::Entitlement},
590 },
591 channel::Channel,
592 guild::{MemberFlags, PartialMember, Permissions},
593 id::Id,
594 oauth::ApplicationIntegrationMap,
595 test::image_hash,
596 user::User,
597 util::datetime::{Timestamp, TimestampParseError},
598 };
599 use serde_test::Token;
600 use std::{collections::HashMap, str::FromStr};
601
602 #[test]
603 #[allow(clippy::too_many_lines, deprecated)]
604 fn test_interaction_full() -> Result<(), TimestampParseError> {
605 let joined_at = Some(Timestamp::from_str("2020-01-01T00:00:00.000000+00:00")?);
606 let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
607
608 let value = Interaction {
609 app_permissions: Some(Permissions::SEND_MESSAGES),
610 application_id: Id::new(100),
611 attachment_size_limit: 8_388_608,
612 authorizing_integration_owners: ApplicationIntegrationMap {
613 guild: None,
614 user: None,
615 },
616 channel: Some(Channel {
617 bitrate: None,
618 guild_id: None,
619 id: Id::new(400),
620 kind: crate::channel::ChannelType::GuildText,
621 last_message_id: None,
622 last_pin_timestamp: None,
623 name: None,
624 nsfw: None,
625 owner_id: None,
626 parent_id: None,
627 permission_overwrites: None,
628 position: None,
629 rate_limit_per_user: None,
630 recipients: None,
631 rtc_region: None,
632 topic: None,
633 user_limit: None,
634 application_id: None,
635 applied_tags: None,
636 available_tags: None,
637 default_auto_archive_duration: None,
638 default_forum_layout: None,
639 default_reaction_emoji: None,
640 default_sort_order: None,
641 default_thread_rate_limit_per_user: None,
642 flags: None,
643 icon: None,
644 invitable: None,
645 managed: None,
646 member: None,
647 member_count: None,
648 message_count: None,
649 newly_created: None,
650 thread_metadata: None,
651 total_message_sent: None,
652 video_quality_mode: None,
653 }),
654 channel_id: Some(Id::new(200)),
655 context: None,
656 data: Some(InteractionData::ApplicationCommand(Box::new(CommandData {
657 guild_id: None,
658 id: Id::new(300),
659 kind: CommandType::ChatInput,
660 name: "command name".into(),
661 options: Vec::from([CommandDataOption {
662 name: "member".into(),
663 value: CommandOptionValue::User(Id::new(600)),
664 }]),
665 resolved: Some(InteractionDataResolved {
666 attachments: HashMap::new(),
667 channels: HashMap::new(),
668 members: IntoIterator::into_iter([(
669 Id::new(600),
670 InteractionMember {
671 avatar: None,
672 avatar_decoration_data: None,
673 banner: None,
674 communication_disabled_until: None,
675 flags,
676 joined_at,
677 nick: Some("nickname".into()),
678 pending: false,
679 permissions: Permissions::empty(),
680 premium_since: None,
681 roles: Vec::new(),
682 },
683 )])
684 .collect(),
685 messages: HashMap::new(),
686 roles: HashMap::new(),
687 users: IntoIterator::into_iter([(
688 Id::new(600),
689 User {
690 accent_color: None,
691 avatar: Some(image_hash::AVATAR),
692 avatar_decoration: None,
693 avatar_decoration_data: None,
694 banner: None,
695 bot: false,
696 discriminator: 1111,
697 email: None,
698 flags: None,
699 global_name: Some("test".into()),
700 id: Id::new(600),
701 locale: None,
702 mfa_enabled: None,
703 name: "username".into(),
704 premium_type: None,
705 primary_guild: None,
706 public_flags: None,
707 system: None,
708 verified: None,
709 },
710 )])
711 .collect(),
712 }),
713 target_id: None,
714 }))),
715 entitlements: vec![Entitlement {
716 application_id: Id::new(100),
717 consumed: Some(false),
718 deleted: false,
719 ends_at: None,
720 guild_id: None,
721 id: Id::new(200),
722 kind: EntitlementType::ApplicationSubscription,
723 sku_id: Id::new(300),
724 starts_at: None,
725 user_id: None,
726 }],
727 guild: None,
728 guild_id: Some(Id::new(400)),
729 guild_locale: Some("de".to_owned()),
730 id: Id::new(500),
731 kind: InteractionType::ApplicationCommand,
732 locale: Some("en-GB".to_owned()),
733 member: Some(PartialMember {
734 avatar: None,
735 avatar_decoration_data: None,
736 banner: None,
737 communication_disabled_until: None,
738 deaf: false,
739 flags,
740 joined_at,
741 mute: false,
742 nick: Some("nickname".into()),
743 permissions: Some(Permissions::empty()),
744 premium_since: None,
745 roles: Vec::new(),
746 user: Some(User {
747 accent_color: None,
748 avatar: Some(image_hash::AVATAR),
749 avatar_decoration: None,
750 avatar_decoration_data: None,
751 banner: None,
752 bot: false,
753 discriminator: 1111,
754 email: None,
755 flags: None,
756 global_name: Some("test".into()),
757 id: Id::new(600),
758 locale: None,
759 mfa_enabled: None,
760 name: "username".into(),
761 premium_type: None,
762 primary_guild: None,
763 public_flags: None,
764 system: None,
765 verified: None,
766 }),
767 }),
768 message: None,
769 token: "interaction token".into(),
770 user: None,
771 };
772
773 serde_test::assert_ser_tokens(
775 &value,
776 &[
777 Token::Struct {
778 name: "Interaction",
779 len: 15,
780 },
781 Token::Str("app_permissions"),
782 Token::Some,
783 Token::Str("2048"),
784 Token::Str("application_id"),
785 Token::NewtypeStruct { name: "Id" },
786 Token::Str("100"),
787 Token::Str("attachment_size_limit"),
788 Token::U64(8_388_608),
789 Token::Str("authorizing_integration_owners"),
790 Token::Struct {
791 name: "ApplicationIntegrationMap",
792 len: 0,
793 },
794 Token::StructEnd,
795 Token::Str("channel"),
796 Token::Some,
797 Token::Struct {
798 name: "Channel",
799 len: 2,
800 },
801 Token::Str("id"),
802 Token::NewtypeStruct { name: "Id" },
803 Token::Str("400"),
804 Token::Str("type"),
805 Token::U8(0),
806 Token::StructEnd,
807 Token::Str("channel_id"),
808 Token::Some,
809 Token::NewtypeStruct { name: "Id" },
810 Token::Str("200"),
811 Token::Str("data"),
812 Token::Some,
813 Token::Struct {
814 name: "CommandData",
815 len: 5,
816 },
817 Token::Str("id"),
818 Token::NewtypeStruct { name: "Id" },
819 Token::Str("300"),
820 Token::Str("type"),
821 Token::U8(1),
822 Token::Str("name"),
823 Token::Str("command name"),
824 Token::Str("options"),
825 Token::Seq { len: Some(1) },
826 Token::Struct {
827 name: "CommandDataOption",
828 len: 3,
829 },
830 Token::Str("name"),
831 Token::Str("member"),
832 Token::Str("type"),
833 Token::U8(CommandOptionType::User as u8),
834 Token::Str("value"),
835 Token::NewtypeStruct { name: "Id" },
836 Token::Str("600"),
837 Token::StructEnd,
838 Token::SeqEnd,
839 Token::Str("resolved"),
840 Token::Some,
841 Token::Struct {
842 name: "InteractionDataResolved",
843 len: 2,
844 },
845 Token::Str("members"),
846 Token::Map { len: Some(1) },
847 Token::NewtypeStruct { name: "Id" },
848 Token::Str("600"),
849 Token::Struct {
850 name: "InteractionMember",
851 len: 7,
852 },
853 Token::Str("communication_disabled_until"),
854 Token::None,
855 Token::Str("flags"),
856 Token::U64(flags.bits()),
857 Token::Str("joined_at"),
858 Token::Some,
859 Token::Str("2020-01-01T00:00:00.000000+00:00"),
860 Token::Str("nick"),
861 Token::Some,
862 Token::Str("nickname"),
863 Token::Str("pending"),
864 Token::Bool(false),
865 Token::Str("permissions"),
866 Token::Str("0"),
867 Token::Str("roles"),
868 Token::Seq { len: Some(0) },
869 Token::SeqEnd,
870 Token::StructEnd,
871 Token::MapEnd,
872 Token::Str("users"),
873 Token::Map { len: Some(1) },
874 Token::NewtypeStruct { name: "Id" },
875 Token::Str("600"),
876 Token::Struct {
877 name: "User",
878 len: 10,
879 },
880 Token::Str("accent_color"),
881 Token::None,
882 Token::Str("avatar"),
883 Token::Some,
884 Token::Str(image_hash::AVATAR_INPUT),
885 Token::Str("avatar_decoration"),
886 Token::None,
887 Token::Str("avatar_decoration_data"),
888 Token::None,
889 Token::Str("banner"),
890 Token::None,
891 Token::Str("bot"),
892 Token::Bool(false),
893 Token::Str("discriminator"),
894 Token::Str("1111"),
895 Token::Str("global_name"),
896 Token::Some,
897 Token::Str("test"),
898 Token::Str("id"),
899 Token::NewtypeStruct { name: "Id" },
900 Token::Str("600"),
901 Token::Str("username"),
902 Token::Str("username"),
903 Token::StructEnd,
904 Token::MapEnd,
905 Token::StructEnd,
906 Token::StructEnd,
907 Token::Str("entitlements"),
908 Token::Seq { len: Some(1) },
909 Token::Struct {
910 name: "Entitlement",
911 len: 6,
912 },
913 Token::Str("application_id"),
914 Token::NewtypeStruct { name: "Id" },
915 Token::Str("100"),
916 Token::Str("consumed"),
917 Token::Some,
918 Token::Bool(false),
919 Token::Str("deleted"),
920 Token::Bool(false),
921 Token::Str("id"),
922 Token::NewtypeStruct { name: "Id" },
923 Token::Str("200"),
924 Token::Str("type"),
925 Token::U8(8),
926 Token::Str("sku_id"),
927 Token::NewtypeStruct { name: "Id" },
928 Token::Str("300"),
929 Token::StructEnd,
930 Token::SeqEnd,
931 Token::Str("guild_id"),
932 Token::Some,
933 Token::NewtypeStruct { name: "Id" },
934 Token::Str("400"),
935 Token::Str("guild_locale"),
936 Token::Some,
937 Token::String("de"),
938 Token::Str("id"),
939 Token::NewtypeStruct { name: "Id" },
940 Token::Str("500"),
941 Token::Str("type"),
942 Token::U8(InteractionType::ApplicationCommand as u8),
943 Token::Str("locale"),
944 Token::Some,
945 Token::Str("en-GB"),
946 Token::Str("member"),
947 Token::Some,
948 Token::Struct {
949 name: "PartialMember",
950 len: 9,
951 },
952 Token::Str("communication_disabled_until"),
953 Token::None,
954 Token::Str("deaf"),
955 Token::Bool(false),
956 Token::Str("flags"),
957 Token::U64(flags.bits()),
958 Token::Str("joined_at"),
959 Token::Some,
960 Token::Str("2020-01-01T00:00:00.000000+00:00"),
961 Token::Str("mute"),
962 Token::Bool(false),
963 Token::Str("nick"),
964 Token::Some,
965 Token::Str("nickname"),
966 Token::Str("permissions"),
967 Token::Some,
968 Token::Str("0"),
969 Token::Str("roles"),
970 Token::Seq { len: Some(0) },
971 Token::SeqEnd,
972 Token::Str("user"),
973 Token::Some,
974 Token::Struct {
975 name: "User",
976 len: 10,
977 },
978 Token::Str("accent_color"),
979 Token::None,
980 Token::Str("avatar"),
981 Token::Some,
982 Token::Str(image_hash::AVATAR_INPUT),
983 Token::Str("avatar_decoration"),
984 Token::None,
985 Token::Str("avatar_decoration_data"),
986 Token::None,
987 Token::Str("banner"),
988 Token::None,
989 Token::Str("bot"),
990 Token::Bool(false),
991 Token::Str("discriminator"),
992 Token::Str("1111"),
993 Token::Str("global_name"),
994 Token::Some,
995 Token::Str("test"),
996 Token::Str("id"),
997 Token::NewtypeStruct { name: "Id" },
998 Token::Str("600"),
999 Token::Str("username"),
1000 Token::Str("username"),
1001 Token::StructEnd,
1002 Token::StructEnd,
1003 Token::Str("token"),
1004 Token::Str("interaction token"),
1005 Token::StructEnd,
1006 ],
1007 );
1008
1009 Ok(())
1010 }
1011}