twilight_model/guild/
mod.rs

1//! Group of [`Channel`]s and [`User`]s with additional moderation options.
2//!
3//! [`Guild`]s allow, for example, assigning [`Role`]s to [`Member`]s to limit
4//! their [`Permissions`] globally, or per [`Channel`].
5//!
6//! [`User`]: super::user::User
7
8pub mod audit_log;
9pub mod auto_moderation;
10pub mod invite;
11pub mod onboarding;
12pub mod scheduled_event;
13pub mod template;
14pub mod widget;
15
16mod afk_timeout;
17mod ban;
18mod default_message_notification_level;
19mod emoji;
20mod explicit_content_filter;
21mod feature;
22mod info;
23mod integration;
24mod integration_account;
25mod integration_application;
26mod integration_expire_behavior;
27mod integration_type;
28mod member;
29mod member_flags;
30mod mfa_level;
31mod nsfw_level;
32mod partial_guild;
33mod partial_member;
34mod permissions;
35mod premium_tier;
36mod preview;
37mod prune;
38mod role;
39mod role_flags;
40mod role_position;
41mod role_tags;
42mod system_channel_flags;
43mod unavailable_guild;
44mod vanity_url;
45mod verification_level;
46
47pub use self::nsfw_level::NSFWLevel;
48pub use self::permissions::Permissions;
49pub use self::{
50    afk_timeout::AfkTimeout, ban::Ban,
51    default_message_notification_level::DefaultMessageNotificationLevel, emoji::Emoji,
52    explicit_content_filter::ExplicitContentFilter, feature::GuildFeature, info::GuildInfo,
53    integration::GuildIntegration, integration_account::IntegrationAccount,
54    integration_application::IntegrationApplication,
55    integration_expire_behavior::IntegrationExpireBehavior, integration_type::GuildIntegrationType,
56    member::Member, member_flags::MemberFlags, mfa_level::MfaLevel, partial_guild::PartialGuild,
57    partial_member::PartialMember, premium_tier::PremiumTier, preview::GuildPreview,
58    prune::GuildPrune, role::Role, role_flags::RoleFlags, role_position::RolePosition,
59    role_tags::RoleTags, system_channel_flags::SystemChannelFlags,
60    unavailable_guild::UnavailableGuild, vanity_url::VanityUrl,
61    verification_level::VerificationLevel, widget::GuildWidget,
62};
63
64use super::gateway::presence::PresenceListDeserializer;
65use crate::{
66    channel::{message::sticker::Sticker, Channel, StageInstance},
67    gateway::presence::Presence,
68    id::{
69        marker::{ApplicationMarker, ChannelMarker, GuildMarker, UserMarker},
70        Id,
71    },
72    util::{ImageHash, Timestamp},
73    voice::VoiceState,
74};
75use serde::{
76    de::{Deserializer, Error as DeError, IgnoredAny, MapAccess, Visitor},
77    Deserialize, Serialize,
78};
79use std::fmt::{Formatter, Result as FmtResult};
80
81#[derive(Clone, Debug, Eq, PartialEq, Serialize, Hash)]
82pub struct Guild {
83    pub afk_channel_id: Option<Id<ChannelMarker>>,
84    pub afk_timeout: AfkTimeout,
85    pub application_id: Option<Id<ApplicationMarker>>,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub approximate_member_count: Option<u64>,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub approximate_presence_count: Option<u64>,
90    pub banner: Option<ImageHash>,
91    #[serde(default)]
92    pub channels: Vec<Channel>,
93    pub default_message_notifications: DefaultMessageNotificationLevel,
94    pub description: Option<String>,
95    pub discovery_splash: Option<ImageHash>,
96    pub emojis: Vec<Emoji>,
97    pub explicit_content_filter: ExplicitContentFilter,
98    /// Enabled guild features
99    pub features: Vec<GuildFeature>,
100    /// Scheduled guild events.
101    #[serde(default, skip_serializing_if = "Vec::is_empty")]
102    pub guild_scheduled_events: Vec<scheduled_event::GuildScheduledEvent>,
103    pub icon: Option<ImageHash>,
104    pub id: Id<GuildMarker>,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub joined_at: Option<Timestamp>,
107    pub large: bool,
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub max_members: Option<u64>,
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub max_presences: Option<u64>,
112    /// Maximum number of users in a stage video channel.
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub max_stage_video_channel_users: Option<u64>,
115    #[serde(skip_serializing_if = "Option::is_none")]
116    pub max_video_channel_users: Option<u64>,
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub member_count: Option<u64>,
119    #[serde(default)]
120    pub members: Vec<Member>,
121    pub mfa_level: MfaLevel,
122    pub name: String,
123    pub nsfw_level: NSFWLevel,
124    pub owner_id: Id<UserMarker>,
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub owner: Option<bool>,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub permissions: Option<Permissions>,
129    pub preferred_locale: String,
130    /// Whether the premium progress bar is enabled in the guild.
131    pub premium_progress_bar_enabled: bool,
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub premium_subscription_count: Option<u64>,
134    #[serde(default)]
135    pub premium_tier: PremiumTier,
136    #[serde(default)]
137    pub presences: Vec<Presence>,
138    /// ID of the where moderators of Community guilds receive notices from
139    /// Discord.
140    pub public_updates_channel_id: Option<Id<ChannelMarker>>,
141    pub roles: Vec<Role>,
142    pub rules_channel_id: Option<Id<ChannelMarker>>,
143    /// The ID of the channel where admins and moderators of Community guilds receive safety alerts from Discord.
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub safety_alerts_channel_id: Option<Id<ChannelMarker>>,
146    pub splash: Option<ImageHash>,
147    #[serde(skip_serializing_if = "Vec::is_empty")]
148    pub stage_instances: Vec<StageInstance>,
149    #[serde(skip_serializing_if = "Vec::is_empty")]
150    pub stickers: Vec<Sticker>,
151    pub system_channel_flags: SystemChannelFlags,
152    pub system_channel_id: Option<Id<ChannelMarker>>,
153    #[serde(default)]
154    pub threads: Vec<Channel>,
155    /// If the guild is unavailable.
156    ///
157    /// # Note:
158    ///
159    /// While it is not documented and may change in the future if
160    /// this field is not sent it is because the user joined a new
161    /// guild.
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub unavailable: Option<bool>,
164    pub vanity_url_code: Option<String>,
165    pub verification_level: VerificationLevel,
166    #[serde(default)]
167    pub voice_states: Vec<VoiceState>,
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub widget_channel_id: Option<Id<ChannelMarker>>,
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub widget_enabled: Option<bool>,
172}
173
174impl<'de> Deserialize<'de> for Guild {
175    #[allow(clippy::too_many_lines)]
176    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
177        #[derive(Debug, Deserialize)]
178        #[serde(field_identifier, rename_all = "snake_case")]
179        enum Field {
180            AfkChannelId,
181            AfkTimeout,
182            ApplicationId,
183            ApproximateMemberCount,
184            ApproximatePresenceCount,
185            Banner,
186            Channels,
187            DefaultMessageNotifications,
188            Description,
189            DiscoverySplash,
190            Emojis,
191            ExplicitContentFilter,
192            Features,
193            GuildScheduledEvents,
194            Icon,
195            Id,
196            JoinedAt,
197            Large,
198            MaxMembers,
199            MaxPresences,
200            MaxStageVideoChannelUsers,
201            MaxVideoChannelUsers,
202            MemberCount,
203            Members,
204            MfaLevel,
205            Name,
206            NsfwLevel,
207            OwnerId,
208            Owner,
209            Permissions,
210            PreferredLocale,
211            PremiumProgressBarEnabled,
212            PremiumSubscriptionCount,
213            PremiumTier,
214            Presences,
215            PublicUpdatesChannelId,
216            Roles,
217            SafetyAlertsChannelId,
218            Splash,
219            StageInstances,
220            Stickers,
221            SystemChannelFlags,
222            SystemChannelId,
223            RulesChannelId,
224            Threads,
225            Unavailable,
226            VerificationLevel,
227            VoiceStates,
228            VanityUrlCode,
229            WidgetChannelId,
230            WidgetEnabled,
231        }
232
233        struct GuildVisitor;
234
235        impl<'de> Visitor<'de> for GuildVisitor {
236            type Value = Guild;
237
238            fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
239                f.write_str("struct Guild")
240            }
241
242            #[allow(clippy::too_many_lines)]
243            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
244                let mut afk_channel_id = None::<Option<_>>;
245                let mut afk_timeout = None;
246                let mut application_id = None::<Option<_>>;
247                let mut approximate_member_count = None::<Option<_>>;
248                let mut approximate_presence_count = None::<Option<_>>;
249                let mut banner = None::<Option<_>>;
250                let mut channels = None::<Vec<Channel>>;
251                let mut default_message_notifications = None;
252                let mut description = None::<Option<_>>;
253                let mut discovery_splash = None::<Option<_>>;
254                let mut emojis = None;
255                let mut explicit_content_filter = None;
256                let mut features = None;
257                let mut guild_scheduled_events = None;
258                let mut icon = None::<Option<_>>;
259                let mut id = None;
260                let mut joined_at = None::<Option<_>>;
261                let mut large = None;
262                let mut max_members = None::<Option<_>>;
263                let mut max_presences = None::<Option<_>>;
264                let mut max_stage_video_channel_users = None::<Option<_>>;
265                let mut max_video_channel_users = None::<Option<_>>;
266                let mut member_count = None::<Option<_>>;
267                let mut members = None;
268                let mut mfa_level = None;
269                let mut name = None;
270                let mut nsfw_level = None;
271                let mut owner = None::<Option<_>>;
272                let mut owner_id = None;
273                let mut permissions = None::<Option<_>>;
274                let mut preferred_locale = None;
275                let mut premium_progress_bar_enabled = None;
276                let mut premium_subscription_count = None::<Option<_>>;
277                let mut premium_tier = None;
278                let mut presences = None;
279                let mut public_updates_channel_id = None::<Option<_>>;
280                let mut roles = None;
281                let mut rules_channel_id = None::<Option<_>>;
282                let mut safety_alerts_channel_id = None::<Option<_>>;
283                let mut splash = None::<Option<_>>;
284                let mut stage_instances = None::<Vec<StageInstance>>;
285                let mut stickers = None::<Vec<Sticker>>;
286                let mut system_channel_flags = None;
287                let mut system_channel_id = None::<Option<_>>;
288                let mut threads = None::<Vec<Channel>>;
289                let mut unavailable = None;
290                let mut vanity_url_code = None::<Option<_>>;
291                let mut verification_level = None;
292                let mut voice_states = None::<Vec<VoiceState>>;
293                let mut widget_channel_id = None::<Option<_>>;
294                let mut widget_enabled = None::<Option<_>>;
295
296                loop {
297                    let key = match map.next_key() {
298                        Ok(Some(key)) => key,
299                        Ok(None) => break,
300                        Err(_) => {
301                            map.next_value::<IgnoredAny>()?;
302
303                            continue;
304                        }
305                    };
306
307                    match key {
308                        Field::AfkChannelId => {
309                            if afk_channel_id.is_some() {
310                                return Err(DeError::duplicate_field("afk_channel_id"));
311                            }
312
313                            afk_channel_id = Some(map.next_value()?);
314                        }
315                        Field::AfkTimeout => {
316                            if afk_timeout.is_some() {
317                                return Err(DeError::duplicate_field("afk_timeout"));
318                            }
319
320                            afk_timeout = Some(map.next_value()?);
321                        }
322                        Field::ApplicationId => {
323                            if application_id.is_some() {
324                                return Err(DeError::duplicate_field("application_id"));
325                            }
326
327                            application_id = Some(map.next_value()?);
328                        }
329                        Field::ApproximateMemberCount => {
330                            if approximate_member_count.is_some() {
331                                return Err(DeError::duplicate_field("approximate_member_count"));
332                            }
333
334                            approximate_member_count = Some(map.next_value()?);
335                        }
336                        Field::ApproximatePresenceCount => {
337                            if approximate_presence_count.is_some() {
338                                return Err(DeError::duplicate_field("approximate_presence_count"));
339                            }
340
341                            approximate_presence_count = Some(map.next_value()?);
342                        }
343                        Field::Banner => {
344                            if banner.is_some() {
345                                return Err(DeError::duplicate_field("banner"));
346                            }
347
348                            banner = Some(map.next_value()?);
349                        }
350                        Field::Channels => {
351                            if channels.is_some() {
352                                return Err(DeError::duplicate_field("channels"));
353                            }
354
355                            channels = Some(map.next_value()?);
356                        }
357                        Field::DefaultMessageNotifications => {
358                            if default_message_notifications.is_some() {
359                                return Err(DeError::duplicate_field(
360                                    "default_message_notifications",
361                                ));
362                            }
363
364                            default_message_notifications = Some(map.next_value()?);
365                        }
366                        Field::Description => {
367                            if description.is_some() {
368                                return Err(DeError::duplicate_field("description"));
369                            }
370
371                            description = Some(map.next_value()?);
372                        }
373                        Field::DiscoverySplash => {
374                            if discovery_splash.is_some() {
375                                return Err(DeError::duplicate_field("discovery_splash"));
376                            }
377
378                            discovery_splash = Some(map.next_value()?);
379                        }
380                        Field::Emojis => {
381                            if emojis.is_some() {
382                                return Err(DeError::duplicate_field("emojis"));
383                            }
384
385                            emojis = Some(map.next_value()?);
386                        }
387                        Field::ExplicitContentFilter => {
388                            if explicit_content_filter.is_some() {
389                                return Err(DeError::duplicate_field("explicit_content_filter"));
390                            }
391
392                            explicit_content_filter = Some(map.next_value()?);
393                        }
394                        Field::Features => {
395                            if features.is_some() {
396                                return Err(DeError::duplicate_field("features"));
397                            }
398
399                            features = Some(map.next_value()?);
400                        }
401                        Field::GuildScheduledEvents => {
402                            if guild_scheduled_events.is_some() {
403                                return Err(DeError::duplicate_field("guild_scheduled_events"));
404                            }
405
406                            guild_scheduled_events = Some(map.next_value()?);
407                        }
408                        Field::Icon => {
409                            if icon.is_some() {
410                                return Err(DeError::duplicate_field("icon"));
411                            }
412
413                            icon = Some(map.next_value()?);
414                        }
415                        Field::Id => {
416                            if id.is_some() {
417                                return Err(DeError::duplicate_field("id"));
418                            }
419
420                            id = Some(map.next_value()?);
421                        }
422                        Field::JoinedAt => {
423                            if joined_at.is_some() {
424                                return Err(DeError::duplicate_field("joined_at"));
425                            }
426
427                            joined_at = Some(map.next_value()?);
428                        }
429                        Field::Large => {
430                            if large.is_some() {
431                                return Err(DeError::duplicate_field("large"));
432                            }
433
434                            large = Some(map.next_value()?);
435                        }
436                        Field::MaxMembers => {
437                            if max_members.is_some() {
438                                return Err(DeError::duplicate_field("max_members"));
439                            }
440
441                            max_members = Some(map.next_value()?);
442                        }
443                        Field::MaxPresences => {
444                            if max_presences.is_some() {
445                                return Err(DeError::duplicate_field("max_presences"));
446                            }
447
448                            max_presences = Some(map.next_value()?);
449                        }
450                        Field::MaxStageVideoChannelUsers => {
451                            if max_stage_video_channel_users.is_some() {
452                                return Err(DeError::duplicate_field(
453                                    "max_stage_video_channel_users",
454                                ));
455                            }
456
457                            max_stage_video_channel_users = Some(map.next_value()?);
458                        }
459                        Field::MaxVideoChannelUsers => {
460                            if max_video_channel_users.is_some() {
461                                return Err(DeError::duplicate_field("max_video_channel_users"));
462                            }
463
464                            max_video_channel_users = Some(map.next_value()?);
465                        }
466                        Field::MemberCount => {
467                            if member_count.is_some() {
468                                return Err(DeError::duplicate_field("member_count"));
469                            }
470
471                            member_count = Some(map.next_value()?);
472                        }
473                        Field::Members => {
474                            if members.is_some() {
475                                return Err(DeError::duplicate_field("members"));
476                            }
477
478                            members = Some(map.next_value()?);
479                        }
480                        Field::MfaLevel => {
481                            if mfa_level.is_some() {
482                                return Err(DeError::duplicate_field("mfa_level"));
483                            }
484
485                            mfa_level = Some(map.next_value()?);
486                        }
487                        Field::Name => {
488                            if name.is_some() {
489                                return Err(DeError::duplicate_field("name"));
490                            }
491
492                            name = Some(map.next_value()?);
493                        }
494                        Field::NsfwLevel => {
495                            if nsfw_level.is_some() {
496                                return Err(DeError::duplicate_field("nsfw_level"));
497                            }
498
499                            nsfw_level = Some(map.next_value()?);
500                        }
501                        Field::Owner => {
502                            if owner.is_some() {
503                                return Err(DeError::duplicate_field("owner"));
504                            }
505
506                            owner = Some(map.next_value()?);
507                        }
508                        Field::OwnerId => {
509                            if owner_id.is_some() {
510                                return Err(DeError::duplicate_field("owner_id"));
511                            }
512
513                            owner_id = Some(map.next_value()?);
514                        }
515                        Field::Permissions => {
516                            if permissions.is_some() {
517                                return Err(DeError::duplicate_field("permissions"));
518                            }
519
520                            permissions = Some(map.next_value()?);
521                        }
522                        Field::PreferredLocale => {
523                            if preferred_locale.is_some() {
524                                return Err(DeError::duplicate_field("preferred_locale"));
525                            }
526
527                            preferred_locale = Some(map.next_value()?);
528                        }
529                        Field::PremiumProgressBarEnabled => {
530                            if premium_progress_bar_enabled.is_some() {
531                                return Err(DeError::duplicate_field(
532                                    "premium_progress_bar_enabled",
533                                ));
534                            }
535
536                            premium_progress_bar_enabled = Some(map.next_value()?);
537                        }
538                        Field::PremiumSubscriptionCount => {
539                            if premium_subscription_count.is_some() {
540                                return Err(DeError::duplicate_field("premium_subscription_count"));
541                            }
542
543                            premium_subscription_count = Some(map.next_value()?);
544                        }
545                        Field::PremiumTier => {
546                            if premium_tier.is_some() {
547                                return Err(DeError::duplicate_field("premium_tier"));
548                            }
549
550                            premium_tier = Some(map.next_value()?);
551                        }
552                        Field::Presences => {
553                            if presences.is_some() {
554                                return Err(DeError::duplicate_field("presences"));
555                            }
556
557                            let deserializer = PresenceListDeserializer::new(Id::new(1));
558
559                            presences = Some(map.next_value_seed(deserializer)?);
560                        }
561                        Field::PublicUpdatesChannelId => {
562                            if public_updates_channel_id.is_some() {
563                                return Err(DeError::duplicate_field("public_updates_channel_id"));
564                            }
565
566                            public_updates_channel_id = Some(map.next_value()?);
567                        }
568                        Field::Roles => {
569                            if roles.is_some() {
570                                return Err(DeError::duplicate_field("roles"));
571                            }
572
573                            roles = Some(map.next_value()?);
574                        }
575                        Field::SafetyAlertsChannelId => {
576                            if safety_alerts_channel_id.is_some() {
577                                return Err(DeError::duplicate_field("safety_alerts_channel_id"));
578                            }
579
580                            safety_alerts_channel_id = Some(map.next_value()?);
581                        }
582                        Field::Splash => {
583                            if splash.is_some() {
584                                return Err(DeError::duplicate_field("splash"));
585                            }
586
587                            splash = Some(map.next_value()?);
588                        }
589                        Field::StageInstances => {
590                            if stage_instances.is_some() {
591                                return Err(DeError::duplicate_field("stage_instances"));
592                            }
593
594                            stage_instances = Some(map.next_value()?);
595                        }
596                        Field::Stickers => {
597                            if stickers.is_some() {
598                                return Err(DeError::duplicate_field("stickers"));
599                            }
600
601                            stickers = Some(map.next_value()?);
602                        }
603                        Field::SystemChannelId => {
604                            if system_channel_id.is_some() {
605                                return Err(DeError::duplicate_field("system_channel_id"));
606                            }
607
608                            system_channel_id = Some(map.next_value()?);
609                        }
610                        Field::SystemChannelFlags => {
611                            if system_channel_flags.is_some() {
612                                return Err(DeError::duplicate_field("system_channel_flags"));
613                            }
614
615                            system_channel_flags = Some(map.next_value()?);
616                        }
617                        Field::RulesChannelId => {
618                            if rules_channel_id.is_some() {
619                                return Err(DeError::duplicate_field("rules_channel_id"));
620                            }
621
622                            rules_channel_id = Some(map.next_value()?);
623                        }
624                        Field::Threads => {
625                            if threads.is_some() {
626                                return Err(DeError::duplicate_field("threads"));
627                            }
628
629                            threads = Some(map.next_value()?);
630                        }
631                        Field::Unavailable => {
632                            if unavailable.is_some() {
633                                return Err(DeError::duplicate_field("unavailable"));
634                            }
635
636                            unavailable = Some(map.next_value()?);
637                        }
638                        Field::VerificationLevel => {
639                            if verification_level.is_some() {
640                                return Err(DeError::duplicate_field("verification_level"));
641                            }
642
643                            verification_level = Some(map.next_value()?);
644                        }
645                        Field::VoiceStates => {
646                            if voice_states.is_some() {
647                                return Err(DeError::duplicate_field("voice_states"));
648                            }
649
650                            voice_states = Some(map.next_value()?);
651                        }
652                        Field::VanityUrlCode => {
653                            if vanity_url_code.is_some() {
654                                return Err(DeError::duplicate_field("vanity_url_code"));
655                            }
656
657                            vanity_url_code = Some(map.next_value()?);
658                        }
659                        Field::WidgetChannelId => {
660                            if widget_channel_id.is_some() {
661                                return Err(DeError::duplicate_field("widget_channel_id"));
662                            }
663
664                            widget_channel_id = Some(map.next_value()?);
665                        }
666                        Field::WidgetEnabled => {
667                            if widget_enabled.is_some() {
668                                return Err(DeError::duplicate_field("widget_enabled"));
669                            }
670
671                            widget_enabled = Some(map.next_value()?);
672                        }
673                    }
674                }
675
676                let afk_timeout =
677                    afk_timeout.ok_or_else(|| DeError::missing_field("afk_timeout"))?;
678                let default_message_notifications = default_message_notifications
679                    .ok_or_else(|| DeError::missing_field("default_message_notifications"))?;
680                let explicit_content_filter = explicit_content_filter
681                    .ok_or_else(|| DeError::missing_field("explicit_content_filter"))?;
682                let features = features.ok_or_else(|| DeError::missing_field("features"))?;
683                let id = id.ok_or_else(|| DeError::missing_field("id"))?;
684                let mfa_level = mfa_level.ok_or_else(|| DeError::missing_field("mfa_level"))?;
685                let name = name.ok_or_else(|| DeError::missing_field("name"))?;
686                let owner_id = owner_id.ok_or_else(|| DeError::missing_field("owner_id"))?;
687                let preferred_locale =
688                    preferred_locale.ok_or_else(|| DeError::missing_field("preferred_locale"))?;
689                let roles = roles.ok_or_else(|| DeError::missing_field("roles"))?;
690                let system_channel_flags = system_channel_flags
691                    .ok_or_else(|| DeError::missing_field("system_channel_flags"))?;
692                let premium_progress_bar_enabled = premium_progress_bar_enabled
693                    .ok_or_else(|| DeError::missing_field("premium_progress_bar_enabled"))?;
694                let verification_level = verification_level
695                    .ok_or_else(|| DeError::missing_field("verification_level"))?;
696
697                let afk_channel_id = afk_channel_id.unwrap_or_default();
698                let application_id = application_id.unwrap_or_default();
699                let approximate_member_count = approximate_member_count.unwrap_or_default();
700                let approximate_presence_count = approximate_presence_count.unwrap_or_default();
701                let banner = banner.unwrap_or_default();
702                let mut channels = channels.unwrap_or_default();
703                let description = description.unwrap_or_default();
704                let discovery_splash = discovery_splash.unwrap_or_default();
705                let emojis = emojis.unwrap_or_default();
706                let guild_scheduled_events = guild_scheduled_events.unwrap_or_default();
707                let icon = icon.unwrap_or_default();
708                let large = large.unwrap_or_default();
709                let joined_at = joined_at.unwrap_or_default();
710                let max_members = max_members.unwrap_or_default();
711                let max_presences = max_presences.unwrap_or_default();
712                let max_stage_video_channel_users =
713                    max_stage_video_channel_users.unwrap_or_default();
714                let max_video_channel_users = max_video_channel_users.unwrap_or_default();
715                let member_count = member_count.unwrap_or_default();
716                let members = members.unwrap_or_default();
717                let nsfw_level = nsfw_level.ok_or_else(|| DeError::missing_field("nsfw_level"))?;
718                let owner = owner.unwrap_or_default();
719                let permissions = permissions.unwrap_or_default();
720                let premium_subscription_count = premium_subscription_count.unwrap_or_default();
721                let premium_tier = premium_tier.unwrap_or_default();
722                let mut presences = presences.unwrap_or_default();
723                let public_updates_channel_id = public_updates_channel_id.unwrap_or_default();
724                let rules_channel_id = rules_channel_id.unwrap_or_default();
725                let safety_alerts_channel_id = safety_alerts_channel_id.unwrap_or_default();
726                let splash = splash.unwrap_or_default();
727                let stage_instances = stage_instances.unwrap_or_default();
728                let stickers = stickers.unwrap_or_default();
729                let system_channel_id = system_channel_id.unwrap_or_default();
730                let mut threads = threads.unwrap_or_default();
731                let vanity_url_code = vanity_url_code.unwrap_or_default();
732                let mut voice_states = voice_states.unwrap_or_default();
733                let widget_channel_id = widget_channel_id.unwrap_or_default();
734                let widget_enabled = widget_enabled.unwrap_or_default();
735
736                for channel in &mut channels {
737                    channel.guild_id = Some(id);
738                }
739
740                for presence in &mut presences {
741                    presence.guild_id = id;
742                }
743
744                for thread in &mut threads {
745                    thread.guild_id = Some(id);
746                }
747
748                for voice_state in &mut voice_states {
749                    voice_state.guild_id.replace(id);
750                }
751
752                Ok(Guild {
753                    afk_channel_id,
754                    afk_timeout,
755                    application_id,
756                    approximate_member_count,
757                    approximate_presence_count,
758                    banner,
759                    channels,
760                    default_message_notifications,
761                    description,
762                    discovery_splash,
763                    emojis,
764                    explicit_content_filter,
765                    features,
766                    guild_scheduled_events,
767                    icon,
768                    id,
769                    joined_at,
770                    large,
771                    max_members,
772                    max_presences,
773                    max_stage_video_channel_users,
774                    max_video_channel_users,
775                    member_count,
776                    members,
777                    mfa_level,
778                    name,
779                    nsfw_level,
780                    owner_id,
781                    owner,
782                    permissions,
783                    preferred_locale,
784                    premium_progress_bar_enabled,
785                    premium_subscription_count,
786                    premium_tier,
787                    presences,
788                    public_updates_channel_id,
789                    roles,
790                    rules_channel_id,
791                    safety_alerts_channel_id,
792                    splash,
793                    stage_instances,
794                    stickers,
795                    system_channel_flags,
796                    system_channel_id,
797                    threads,
798                    unavailable,
799                    vanity_url_code,
800                    verification_level,
801                    voice_states,
802                    widget_channel_id,
803                    widget_enabled,
804                })
805            }
806        }
807
808        const FIELDS: &[&str] = &[
809            "afk_channel_id",
810            "afk_timeout",
811            "application_id",
812            "approximate_member_count",
813            "approximate_presence_count",
814            "banner",
815            "channels",
816            "default_message_notifications",
817            "description",
818            "discovery_splash",
819            "emojis",
820            "explicit_content_filter",
821            "features",
822            "icon",
823            "id",
824            "joined_at",
825            "large",
826            "max_members",
827            "max_presences",
828            "max_video_channel_users",
829            "member_count",
830            "members",
831            "mfa_level",
832            "name",
833            "nsfw_level",
834            "owner",
835            "owner_id",
836            "permissions",
837            "preferred_locale",
838            "premium_progress_bar_enabled",
839            "premium_subscription_count",
840            "premium_tier",
841            "presences",
842            "public_updates_channel_id",
843            "roles",
844            "splash",
845            "system_channel_id",
846            "system_channel_flags",
847            "rules_channel_id",
848            "threads",
849            "unavailable",
850            "verification_level",
851            "voice_states",
852            "vanity_url_code",
853            "widget_channel_id",
854            "widget_enabled",
855        ];
856
857        deserializer.deserialize_struct("Guild", FIELDS, GuildVisitor)
858    }
859}
860
861#[cfg(test)]
862mod tests {
863    use super::{
864        AfkTimeout, DefaultMessageNotificationLevel, ExplicitContentFilter, Guild, GuildFeature,
865        MfaLevel, NSFWLevel, Permissions, PremiumTier, SystemChannelFlags, VerificationLevel,
866    };
867    use crate::{
868        id::Id,
869        test::image_hash,
870        util::datetime::{Timestamp, TimestampParseError},
871    };
872    use serde_test::Token;
873    use std::str::FromStr;
874
875    #[allow(clippy::too_many_lines)]
876    #[test]
877    fn guild() -> Result<(), TimestampParseError> {
878        let joined_at = Some(Timestamp::from_str("2015-04-26T06:26:56.936000+00:00")?);
879
880        let value = Guild {
881            afk_channel_id: Some(Id::new(2)),
882            afk_timeout: AfkTimeout::FIFTEEN_MINUTES,
883            application_id: Some(Id::new(3)),
884            approximate_member_count: Some(1_200),
885            approximate_presence_count: Some(900),
886            banner: Some(image_hash::BANNER),
887            channels: Vec::new(),
888            default_message_notifications: DefaultMessageNotificationLevel::Mentions,
889            description: Some("a description".to_owned()),
890            discovery_splash: Some(image_hash::SPLASH),
891            emojis: Vec::new(),
892            explicit_content_filter: ExplicitContentFilter::MembersWithoutRole,
893            features: Vec::from([GuildFeature::Banner]),
894            guild_scheduled_events: Vec::new(),
895            icon: Some(image_hash::ICON),
896            id: Id::new(1),
897            joined_at,
898            large: true,
899            max_members: Some(25_000),
900            max_presences: Some(10_000),
901            max_stage_video_channel_users: Some(10),
902            max_video_channel_users: Some(10),
903            member_count: Some(12_000),
904            members: Vec::new(),
905            mfa_level: MfaLevel::Elevated,
906            name: "the name".to_owned(),
907            nsfw_level: NSFWLevel::Default,
908            owner_id: Id::new(5),
909            owner: Some(false),
910            permissions: Some(Permissions::SEND_MESSAGES),
911            preferred_locale: "en-us".to_owned(),
912            premium_progress_bar_enabled: false,
913            premium_subscription_count: Some(3),
914            premium_tier: PremiumTier::Tier1,
915            presences: Vec::new(),
916            public_updates_channel_id: None,
917            roles: Vec::new(),
918            rules_channel_id: Some(Id::new(6)),
919            safety_alerts_channel_id: Some(Id::new(9)),
920            splash: Some(image_hash::SPLASH),
921            stage_instances: Vec::new(),
922            stickers: Vec::new(),
923            system_channel_flags: SystemChannelFlags::SUPPRESS_PREMIUM_SUBSCRIPTIONS,
924            system_channel_id: Some(Id::new(7)),
925            threads: Vec::new(),
926            unavailable: None,
927            vanity_url_code: Some("twilight".to_owned()),
928            verification_level: VerificationLevel::Medium,
929            voice_states: Vec::new(),
930            widget_channel_id: Some(Id::new(8)),
931            widget_enabled: Some(true),
932        };
933
934        serde_test::assert_tokens(
935            &value,
936            &[
937                Token::Struct {
938                    name: "Guild",
939                    len: 47,
940                },
941                Token::Str("afk_channel_id"),
942                Token::Some,
943                Token::NewtypeStruct { name: "Id" },
944                Token::Str("2"),
945                Token::Str("afk_timeout"),
946                Token::NewtypeStruct { name: "AfkTimeout" },
947                Token::U16(900),
948                Token::Str("application_id"),
949                Token::Some,
950                Token::NewtypeStruct { name: "Id" },
951                Token::Str("3"),
952                Token::Str("approximate_member_count"),
953                Token::Some,
954                Token::U64(1_200),
955                Token::Str("approximate_presence_count"),
956                Token::Some,
957                Token::U64(900),
958                Token::Str("banner"),
959                Token::Some,
960                Token::Str(image_hash::BANNER_INPUT),
961                Token::Str("channels"),
962                Token::Seq { len: Some(0) },
963                Token::SeqEnd,
964                Token::Str("default_message_notifications"),
965                Token::U8(1),
966                Token::Str("description"),
967                Token::Some,
968                Token::Str("a description"),
969                Token::Str("discovery_splash"),
970                Token::Some,
971                Token::Str(image_hash::SPLASH_INPUT),
972                Token::Str("emojis"),
973                Token::Seq { len: Some(0) },
974                Token::SeqEnd,
975                Token::Str("explicit_content_filter"),
976                Token::U8(1),
977                Token::Str("features"),
978                Token::Seq { len: Some(1) },
979                Token::Str("BANNER"),
980                Token::SeqEnd,
981                Token::Str("icon"),
982                Token::Some,
983                Token::Str(image_hash::ICON_INPUT),
984                Token::Str("id"),
985                Token::NewtypeStruct { name: "Id" },
986                Token::Str("1"),
987                Token::Str("joined_at"),
988                Token::Some,
989                Token::Str("2015-04-26T06:26:56.936000+00:00"),
990                Token::Str("large"),
991                Token::Bool(true),
992                Token::Str("max_members"),
993                Token::Some,
994                Token::U64(25_000),
995                Token::Str("max_presences"),
996                Token::Some,
997                Token::U64(10_000),
998                Token::Str("max_stage_video_channel_users"),
999                Token::Some,
1000                Token::U64(10),
1001                Token::Str("max_video_channel_users"),
1002                Token::Some,
1003                Token::U64(10),
1004                Token::Str("member_count"),
1005                Token::Some,
1006                Token::U64(12_000),
1007                Token::Str("members"),
1008                Token::Seq { len: Some(0) },
1009                Token::SeqEnd,
1010                Token::Str("mfa_level"),
1011                Token::U8(1),
1012                Token::Str("name"),
1013                Token::Str("the name"),
1014                Token::Str("nsfw_level"),
1015                Token::U8(0),
1016                Token::Str("owner_id"),
1017                Token::NewtypeStruct { name: "Id" },
1018                Token::Str("5"),
1019                Token::Str("owner"),
1020                Token::Some,
1021                Token::Bool(false),
1022                Token::Str("permissions"),
1023                Token::Some,
1024                Token::Str("2048"),
1025                Token::Str("preferred_locale"),
1026                Token::Str("en-us"),
1027                Token::Str("premium_progress_bar_enabled"),
1028                Token::Bool(false),
1029                Token::Str("premium_subscription_count"),
1030                Token::Some,
1031                Token::U64(3),
1032                Token::Str("premium_tier"),
1033                Token::U8(1),
1034                Token::Str("presences"),
1035                Token::Seq { len: Some(0) },
1036                Token::SeqEnd,
1037                Token::Str("public_updates_channel_id"),
1038                Token::None,
1039                Token::Str("roles"),
1040                Token::Seq { len: Some(0) },
1041                Token::SeqEnd,
1042                Token::Str("rules_channel_id"),
1043                Token::Some,
1044                Token::NewtypeStruct { name: "Id" },
1045                Token::Str("6"),
1046                Token::Str("safety_alerts_channel_id"),
1047                Token::Some,
1048                Token::NewtypeStruct { name: "Id" },
1049                Token::Str("9"),
1050                Token::Str("splash"),
1051                Token::Some,
1052                Token::Str(image_hash::SPLASH_INPUT),
1053                Token::Str("system_channel_flags"),
1054                Token::U64(2),
1055                Token::Str("system_channel_id"),
1056                Token::Some,
1057                Token::NewtypeStruct { name: "Id" },
1058                Token::Str("7"),
1059                Token::Str("threads"),
1060                Token::Seq { len: Some(0) },
1061                Token::SeqEnd,
1062                Token::Str("vanity_url_code"),
1063                Token::Some,
1064                Token::Str("twilight"),
1065                Token::Str("verification_level"),
1066                Token::U8(2),
1067                Token::Str("voice_states"),
1068                Token::Seq { len: Some(0) },
1069                Token::SeqEnd,
1070                Token::Str("widget_channel_id"),
1071                Token::Some,
1072                Token::NewtypeStruct { name: "Id" },
1073                Token::Str("8"),
1074                Token::Str("widget_enabled"),
1075                Token::Some,
1076                Token::Bool(true),
1077                Token::StructEnd,
1078            ],
1079        );
1080
1081        Ok(())
1082    }
1083}