1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::model::id::{ChannelId, EmojiId};

/// Information relating to a guild's welcome screen.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildWelcomeScreen {
    /// The server description shown in the welcome screen.
    pub description: Option<String>,
    /// The channels shown in the welcome screen.
    ///
    /// **Note**: There can only be only up to 5 channels.
    pub welcome_channels: Vec<GuildWelcomeChannel>,
}

/// A channel shown in the [`GuildWelcomeScreen`].
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct GuildWelcomeChannel {
    /// The channel Id.
    pub channel_id: ChannelId,
    /// The description shown for the channel.
    pub description: String,
    /// The emoji shown, if there is one.
    pub emoji: Option<GuildWelcomeChannelEmoji>,
}

impl<'de> Deserialize<'de> for GuildWelcomeChannel {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        #[derive(Deserialize)]
        struct Helper {
            channel_id: ChannelId,
            description: String,
            emoji_id: Option<EmojiId>,
            emoji_name: Option<String>,
        }
        let Helper {
            channel_id,
            description,
            emoji_id,
            emoji_name,
        } = Helper::deserialize(deserializer)?;

        let emoji = match (emoji_id, emoji_name) {
            (Some(id), Some(name)) => Some(GuildWelcomeChannelEmoji::Custom {
                id,
                name,
            }),
            (None, Some(name)) => Some(GuildWelcomeChannelEmoji::Unicode(name)),
            _ => None,
        };

        Ok(Self {
            channel_id,
            description,
            emoji,
        })
    }
}

impl Serialize for GuildWelcomeChannel {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut s = serializer.serialize_struct("GuildWelcomeChannel", 4)?;
        s.serialize_field("channel_id", &self.channel_id)?;
        s.serialize_field("description", &self.description)?;
        let (emoji_id, emoji_name) = match &self.emoji {
            Some(GuildWelcomeChannelEmoji::Custom {
                id,
                name,
            }) => (Some(id), Some(name)),
            Some(GuildWelcomeChannelEmoji::Unicode(name)) => (None, Some(name)),
            None => (None, None),
        };
        s.serialize_field("emoji_id", &emoji_id)?;
        s.serialize_field("emoji_name", &emoji_name)?;
        s.end()
    }
}

/// A [`GuildWelcomeScreen`] emoji.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
#[non_exhaustive]
pub enum GuildWelcomeChannelEmoji {
    /// A custom emoji.
    Custom { id: EmojiId, name: String },
    /// A unicode emoji.
    Unicode(String),
}