serenity/model/guild/
welcome_screen.rs

1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2
3use crate::model::id::{ChannelId, EmojiId};
4
5/// Information relating to a guild's welcome screen.
6///
7/// [Discord docs](https://discord.com/developers/docs/resources/guild#welcome-screen-object).
8#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
9#[derive(Clone, Debug, Deserialize, Serialize)]
10#[non_exhaustive]
11pub struct GuildWelcomeScreen {
12    /// The server description shown in the welcome screen.
13    pub description: Option<String>,
14    /// The channels shown in the welcome screen.
15    ///
16    /// **Note**: There can only be only up to 5 channels.
17    pub welcome_channels: Vec<GuildWelcomeChannel>,
18}
19
20/// A channel shown in the [`GuildWelcomeScreen`].
21///
22/// [Discord docs](https://discord.com/developers/docs/resources/guild#welcome-screen-object-welcome-screen-channel-structure).
23#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
24#[derive(Clone, Debug)]
25#[non_exhaustive]
26pub struct GuildWelcomeChannel {
27    /// The channel Id.
28    pub channel_id: ChannelId,
29    /// The description shown for the channel.
30    pub description: String,
31    /// The emoji shown, if there is one.
32    pub emoji: Option<GuildWelcomeChannelEmoji>,
33}
34
35// Manual impl needed to deserialize emoji_id and emoji_name into a single GuildWelcomeChannelEmoji
36impl<'de> Deserialize<'de> for GuildWelcomeChannel {
37    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
38        #[derive(Deserialize)]
39        struct Helper {
40            channel_id: ChannelId,
41            description: String,
42            emoji_id: Option<EmojiId>,
43            emoji_name: Option<String>,
44        }
45        let Helper {
46            channel_id,
47            description,
48            emoji_id,
49            emoji_name,
50        } = Helper::deserialize(deserializer)?;
51
52        let emoji = match (emoji_id, emoji_name) {
53            (Some(id), Some(name)) => Some(GuildWelcomeChannelEmoji::Custom {
54                id,
55                name,
56            }),
57            (None, Some(name)) => Some(GuildWelcomeChannelEmoji::Unicode(name)),
58            _ => None,
59        };
60
61        Ok(Self {
62            channel_id,
63            description,
64            emoji,
65        })
66    }
67}
68
69impl Serialize for GuildWelcomeChannel {
70    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
71        use serde::ser::SerializeStruct;
72
73        let mut s = serializer.serialize_struct("GuildWelcomeChannel", 4)?;
74        s.serialize_field("channel_id", &self.channel_id)?;
75        s.serialize_field("description", &self.description)?;
76        let (emoji_id, emoji_name) = match &self.emoji {
77            Some(GuildWelcomeChannelEmoji::Custom {
78                id,
79                name,
80            }) => (Some(id), Some(name)),
81            Some(GuildWelcomeChannelEmoji::Unicode(name)) => (None, Some(name)),
82            None => (None, None),
83        };
84        s.serialize_field("emoji_id", &emoji_id)?;
85        s.serialize_field("emoji_name", &emoji_name)?;
86        s.end()
87    }
88}
89
90/// A [`GuildWelcomeScreen`] emoji.
91///
92/// [Discord docs](https://discord.com/developers/docs/resources/guild#welcome-screen-object-welcome-screen-channel-structure).
93#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
94#[derive(Clone, Debug, Eq, PartialEq, Hash)]
95#[non_exhaustive]
96pub enum GuildWelcomeChannelEmoji {
97    /// A custom emoji.
98    Custom { id: EmojiId, name: String },
99    /// A unicode emoji.
100    Unicode(String),
101}