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 video_quality_mode: None,
652 }),
653 channel_id: Some(Id::new(200)),
654 context: None,
655 data: Some(InteractionData::ApplicationCommand(Box::new(CommandData {
656 guild_id: None,
657 id: Id::new(300),
658 kind: CommandType::ChatInput,
659 name: "command name".into(),
660 options: Vec::from([CommandDataOption {
661 name: "member".into(),
662 value: CommandOptionValue::User(Id::new(600)),
663 }]),
664 resolved: Some(InteractionDataResolved {
665 attachments: HashMap::new(),
666 channels: HashMap::new(),
667 members: IntoIterator::into_iter([(
668 Id::new(600),
669 InteractionMember {
670 avatar: None,
671 avatar_decoration_data: None,
672 banner: None,
673 communication_disabled_until: None,
674 flags,
675 joined_at,
676 nick: Some("nickname".into()),
677 pending: false,
678 permissions: Permissions::empty(),
679 premium_since: None,
680 roles: Vec::new(),
681 },
682 )])
683 .collect(),
684 messages: HashMap::new(),
685 roles: HashMap::new(),
686 users: IntoIterator::into_iter([(
687 Id::new(600),
688 User {
689 accent_color: None,
690 avatar: Some(image_hash::AVATAR),
691 avatar_decoration: None,
692 avatar_decoration_data: None,
693 banner: None,
694 bot: false,
695 discriminator: 1111,
696 email: None,
697 flags: None,
698 global_name: Some("test".into()),
699 id: Id::new(600),
700 locale: None,
701 mfa_enabled: None,
702 name: "username".into(),
703 premium_type: None,
704 primary_guild: None,
705 public_flags: None,
706 system: None,
707 verified: None,
708 },
709 )])
710 .collect(),
711 }),
712 target_id: None,
713 }))),
714 entitlements: vec![Entitlement {
715 application_id: Id::new(100),
716 consumed: Some(false),
717 deleted: false,
718 ends_at: None,
719 guild_id: None,
720 id: Id::new(200),
721 kind: EntitlementType::ApplicationSubscription,
722 sku_id: Id::new(300),
723 starts_at: None,
724 user_id: None,
725 }],
726 guild: None,
727 guild_id: Some(Id::new(400)),
728 guild_locale: Some("de".to_owned()),
729 id: Id::new(500),
730 kind: InteractionType::ApplicationCommand,
731 locale: Some("en-GB".to_owned()),
732 member: Some(PartialMember {
733 avatar: None,
734 avatar_decoration_data: None,
735 banner: None,
736 communication_disabled_until: None,
737 deaf: false,
738 flags,
739 joined_at,
740 mute: false,
741 nick: Some("nickname".into()),
742 permissions: Some(Permissions::empty()),
743 premium_since: None,
744 roles: Vec::new(),
745 user: Some(User {
746 accent_color: None,
747 avatar: Some(image_hash::AVATAR),
748 avatar_decoration: None,
749 avatar_decoration_data: None,
750 banner: None,
751 bot: false,
752 discriminator: 1111,
753 email: None,
754 flags: None,
755 global_name: Some("test".into()),
756 id: Id::new(600),
757 locale: None,
758 mfa_enabled: None,
759 name: "username".into(),
760 premium_type: None,
761 primary_guild: None,
762 public_flags: None,
763 system: None,
764 verified: None,
765 }),
766 }),
767 message: None,
768 token: "interaction token".into(),
769 user: None,
770 };
771
772 serde_test::assert_ser_tokens(
774 &value,
775 &[
776 Token::Struct {
777 name: "Interaction",
778 len: 15,
779 },
780 Token::Str("app_permissions"),
781 Token::Some,
782 Token::Str("2048"),
783 Token::Str("application_id"),
784 Token::NewtypeStruct { name: "Id" },
785 Token::Str("100"),
786 Token::Str("attachment_size_limit"),
787 Token::U64(8_388_608),
788 Token::Str("authorizing_integration_owners"),
789 Token::Struct {
790 name: "ApplicationIntegrationMap",
791 len: 0,
792 },
793 Token::StructEnd,
794 Token::Str("channel"),
795 Token::Some,
796 Token::Struct {
797 name: "Channel",
798 len: 2,
799 },
800 Token::Str("id"),
801 Token::NewtypeStruct { name: "Id" },
802 Token::Str("400"),
803 Token::Str("type"),
804 Token::U8(0),
805 Token::StructEnd,
806 Token::Str("channel_id"),
807 Token::Some,
808 Token::NewtypeStruct { name: "Id" },
809 Token::Str("200"),
810 Token::Str("data"),
811 Token::Some,
812 Token::Struct {
813 name: "CommandData",
814 len: 5,
815 },
816 Token::Str("id"),
817 Token::NewtypeStruct { name: "Id" },
818 Token::Str("300"),
819 Token::Str("type"),
820 Token::U8(1),
821 Token::Str("name"),
822 Token::Str("command name"),
823 Token::Str("options"),
824 Token::Seq { len: Some(1) },
825 Token::Struct {
826 name: "CommandDataOption",
827 len: 3,
828 },
829 Token::Str("name"),
830 Token::Str("member"),
831 Token::Str("type"),
832 Token::U8(CommandOptionType::User as u8),
833 Token::Str("value"),
834 Token::NewtypeStruct { name: "Id" },
835 Token::Str("600"),
836 Token::StructEnd,
837 Token::SeqEnd,
838 Token::Str("resolved"),
839 Token::Some,
840 Token::Struct {
841 name: "InteractionDataResolved",
842 len: 2,
843 },
844 Token::Str("members"),
845 Token::Map { len: Some(1) },
846 Token::NewtypeStruct { name: "Id" },
847 Token::Str("600"),
848 Token::Struct {
849 name: "InteractionMember",
850 len: 7,
851 },
852 Token::Str("communication_disabled_until"),
853 Token::None,
854 Token::Str("flags"),
855 Token::U64(flags.bits()),
856 Token::Str("joined_at"),
857 Token::Some,
858 Token::Str("2020-01-01T00:00:00.000000+00:00"),
859 Token::Str("nick"),
860 Token::Some,
861 Token::Str("nickname"),
862 Token::Str("pending"),
863 Token::Bool(false),
864 Token::Str("permissions"),
865 Token::Str("0"),
866 Token::Str("roles"),
867 Token::Seq { len: Some(0) },
868 Token::SeqEnd,
869 Token::StructEnd,
870 Token::MapEnd,
871 Token::Str("users"),
872 Token::Map { len: Some(1) },
873 Token::NewtypeStruct { name: "Id" },
874 Token::Str("600"),
875 Token::Struct {
876 name: "User",
877 len: 10,
878 },
879 Token::Str("accent_color"),
880 Token::None,
881 Token::Str("avatar"),
882 Token::Some,
883 Token::Str(image_hash::AVATAR_INPUT),
884 Token::Str("avatar_decoration"),
885 Token::None,
886 Token::Str("avatar_decoration_data"),
887 Token::None,
888 Token::Str("banner"),
889 Token::None,
890 Token::Str("bot"),
891 Token::Bool(false),
892 Token::Str("discriminator"),
893 Token::Str("1111"),
894 Token::Str("global_name"),
895 Token::Some,
896 Token::Str("test"),
897 Token::Str("id"),
898 Token::NewtypeStruct { name: "Id" },
899 Token::Str("600"),
900 Token::Str("username"),
901 Token::Str("username"),
902 Token::StructEnd,
903 Token::MapEnd,
904 Token::StructEnd,
905 Token::StructEnd,
906 Token::Str("entitlements"),
907 Token::Seq { len: Some(1) },
908 Token::Struct {
909 name: "Entitlement",
910 len: 6,
911 },
912 Token::Str("application_id"),
913 Token::NewtypeStruct { name: "Id" },
914 Token::Str("100"),
915 Token::Str("consumed"),
916 Token::Some,
917 Token::Bool(false),
918 Token::Str("deleted"),
919 Token::Bool(false),
920 Token::Str("id"),
921 Token::NewtypeStruct { name: "Id" },
922 Token::Str("200"),
923 Token::Str("type"),
924 Token::U8(8),
925 Token::Str("sku_id"),
926 Token::NewtypeStruct { name: "Id" },
927 Token::Str("300"),
928 Token::StructEnd,
929 Token::SeqEnd,
930 Token::Str("guild_id"),
931 Token::Some,
932 Token::NewtypeStruct { name: "Id" },
933 Token::Str("400"),
934 Token::Str("guild_locale"),
935 Token::Some,
936 Token::String("de"),
937 Token::Str("id"),
938 Token::NewtypeStruct { name: "Id" },
939 Token::Str("500"),
940 Token::Str("type"),
941 Token::U8(InteractionType::ApplicationCommand as u8),
942 Token::Str("locale"),
943 Token::Some,
944 Token::Str("en-GB"),
945 Token::Str("member"),
946 Token::Some,
947 Token::Struct {
948 name: "PartialMember",
949 len: 9,
950 },
951 Token::Str("communication_disabled_until"),
952 Token::None,
953 Token::Str("deaf"),
954 Token::Bool(false),
955 Token::Str("flags"),
956 Token::U64(flags.bits()),
957 Token::Str("joined_at"),
958 Token::Some,
959 Token::Str("2020-01-01T00:00:00.000000+00:00"),
960 Token::Str("mute"),
961 Token::Bool(false),
962 Token::Str("nick"),
963 Token::Some,
964 Token::Str("nickname"),
965 Token::Str("permissions"),
966 Token::Some,
967 Token::Str("0"),
968 Token::Str("roles"),
969 Token::Seq { len: Some(0) },
970 Token::SeqEnd,
971 Token::Str("user"),
972 Token::Some,
973 Token::Struct {
974 name: "User",
975 len: 10,
976 },
977 Token::Str("accent_color"),
978 Token::None,
979 Token::Str("avatar"),
980 Token::Some,
981 Token::Str(image_hash::AVATAR_INPUT),
982 Token::Str("avatar_decoration"),
983 Token::None,
984 Token::Str("avatar_decoration_data"),
985 Token::None,
986 Token::Str("banner"),
987 Token::None,
988 Token::Str("bot"),
989 Token::Bool(false),
990 Token::Str("discriminator"),
991 Token::Str("1111"),
992 Token::Str("global_name"),
993 Token::Some,
994 Token::Str("test"),
995 Token::Str("id"),
996 Token::NewtypeStruct { name: "Id" },
997 Token::Str("600"),
998 Token::Str("username"),
999 Token::Str("username"),
1000 Token::StructEnd,
1001 Token::StructEnd,
1002 Token::Str("token"),
1003 Token::Str("interaction token"),
1004 Token::StructEnd,
1005 ],
1006 );
1007
1008 Ok(())
1009 }
1010}