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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
use crate::channel::ConversionError;
use serde_repr::{Deserialize_repr, Serialize_repr};

#[derive(Clone, Copy, Debug, Deserialize_repr, Eq, Hash, PartialEq, Serialize_repr)]
#[non_exhaustive]
#[repr(u8)]
pub enum MessageType {
    Regular = 0,
    RecipientAdd = 1,
    RecipientRemove = 2,
    Call = 3,
    ChannelNameChange = 4,
    ChannelIconChange = 5,
    ChannelMessagePinned = 6,
    GuildMemberJoin = 7,
    UserPremiumSub = 8,
    UserPremiumSubTier1 = 9,
    UserPremiumSubTier2 = 10,
    UserPremiumSubTier3 = 11,
    ChannelFollowAdd = 12,
    GuildDiscoveryDisqualified = 14,
    GuildDiscoveryRequalified = 15,
    GuildDiscoveryGracePeriodInitialWarning = 16,
    GuildDiscoveryGracePeriodFinalWarning = 17,
    ThreadCreated = 18,
    /// Message is an inline reply.
    Reply = 19,
    /// Message is a chat input command.
    ChatInputCommand = 20,
    ThreadStarterMessage = 21,
    GuildInviteReminder = 22,
    ContextMenuCommand = 23,
    /// Message is an auto-moderation action.
    AutoModerationAction = 24,
}

impl TryFrom<u8> for MessageType {
    type Error = ConversionError;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        let message_type = match value {
            0 => MessageType::Regular,
            1 => MessageType::RecipientAdd,
            2 => MessageType::RecipientRemove,
            3 => MessageType::Call,
            4 => MessageType::ChannelNameChange,
            5 => MessageType::ChannelIconChange,
            6 => MessageType::ChannelMessagePinned,
            7 => MessageType::GuildMemberJoin,
            8 => MessageType::UserPremiumSub,
            9 => MessageType::UserPremiumSubTier1,
            10 => MessageType::UserPremiumSubTier2,
            11 => MessageType::UserPremiumSubTier3,
            12 => MessageType::ChannelFollowAdd,
            14 => MessageType::GuildDiscoveryDisqualified,
            15 => MessageType::GuildDiscoveryRequalified,
            16 => MessageType::GuildDiscoveryGracePeriodInitialWarning,
            17 => MessageType::GuildDiscoveryGracePeriodFinalWarning,
            18 => MessageType::ThreadCreated,
            19 => MessageType::Reply,
            20 => MessageType::ChatInputCommand,
            21 => MessageType::ThreadStarterMessage,
            22 => MessageType::GuildInviteReminder,
            23 => MessageType::ContextMenuCommand,
            24 => MessageType::AutoModerationAction,
            _ => return Err(ConversionError::MessageType(value)),
        };

        Ok(message_type)
    }
}

#[cfg(test)]
mod tests {
    use super::{ConversionError, MessageType};
    use serde_test::Token;

    #[test]
    fn variants() {
        serde_test::assert_tokens(&MessageType::Regular, &[Token::U8(0)]);
        serde_test::assert_tokens(&MessageType::RecipientAdd, &[Token::U8(1)]);
        serde_test::assert_tokens(&MessageType::RecipientRemove, &[Token::U8(2)]);
        serde_test::assert_tokens(&MessageType::Call, &[Token::U8(3)]);
        serde_test::assert_tokens(&MessageType::ChannelNameChange, &[Token::U8(4)]);
        serde_test::assert_tokens(&MessageType::ChannelIconChange, &[Token::U8(5)]);
        serde_test::assert_tokens(&MessageType::ChannelMessagePinned, &[Token::U8(6)]);
        serde_test::assert_tokens(&MessageType::GuildMemberJoin, &[Token::U8(7)]);
        serde_test::assert_tokens(&MessageType::UserPremiumSub, &[Token::U8(8)]);
        serde_test::assert_tokens(&MessageType::UserPremiumSubTier1, &[Token::U8(9)]);
        serde_test::assert_tokens(&MessageType::UserPremiumSubTier2, &[Token::U8(10)]);
        serde_test::assert_tokens(&MessageType::UserPremiumSubTier3, &[Token::U8(11)]);
        serde_test::assert_tokens(&MessageType::ChannelFollowAdd, &[Token::U8(12)]);
        serde_test::assert_tokens(&MessageType::GuildDiscoveryDisqualified, &[Token::U8(14)]);
        serde_test::assert_tokens(&MessageType::GuildDiscoveryRequalified, &[Token::U8(15)]);
        serde_test::assert_tokens(
            &MessageType::GuildDiscoveryGracePeriodInitialWarning,
            &[Token::U8(16)],
        );
        serde_test::assert_tokens(
            &MessageType::GuildDiscoveryGracePeriodFinalWarning,
            &[Token::U8(17)],
        );
        serde_test::assert_tokens(&MessageType::ThreadCreated, &[Token::U8(18)]);
        serde_test::assert_tokens(&MessageType::Reply, &[Token::U8(19)]);
        serde_test::assert_tokens(&MessageType::ChatInputCommand, &[Token::U8(20)]);
        serde_test::assert_tokens(&MessageType::ThreadStarterMessage, &[Token::U8(21)]);
        serde_test::assert_tokens(&MessageType::GuildInviteReminder, &[Token::U8(22)]);
        serde_test::assert_tokens(&MessageType::ContextMenuCommand, &[Token::U8(23)]);
        serde_test::assert_tokens(&MessageType::AutoModerationAction, &[Token::U8(24)]);
    }

    #[test]
    fn conversions() {
        assert_eq!(MessageType::try_from(0).unwrap(), MessageType::Regular);
        assert_eq!(MessageType::try_from(1).unwrap(), MessageType::RecipientAdd);
        assert_eq!(
            MessageType::try_from(2).unwrap(),
            MessageType::RecipientRemove
        );
        assert_eq!(MessageType::try_from(3).unwrap(), MessageType::Call);
        assert_eq!(
            MessageType::try_from(4).unwrap(),
            MessageType::ChannelNameChange
        );
        assert_eq!(
            MessageType::try_from(5).unwrap(),
            MessageType::ChannelIconChange
        );
        assert_eq!(
            MessageType::try_from(6).unwrap(),
            MessageType::ChannelMessagePinned
        );
        assert_eq!(
            MessageType::try_from(7).unwrap(),
            MessageType::GuildMemberJoin
        );
        assert_eq!(
            MessageType::try_from(8).unwrap(),
            MessageType::UserPremiumSub
        );
        assert_eq!(
            MessageType::try_from(9).unwrap(),
            MessageType::UserPremiumSubTier1
        );
        assert_eq!(
            MessageType::try_from(10).unwrap(),
            MessageType::UserPremiumSubTier2
        );
        assert_eq!(
            MessageType::try_from(11).unwrap(),
            MessageType::UserPremiumSubTier3
        );
        assert_eq!(
            MessageType::try_from(12).unwrap(),
            MessageType::ChannelFollowAdd
        );
        assert_eq!(
            MessageType::try_from(14).unwrap(),
            MessageType::GuildDiscoveryDisqualified
        );
        assert_eq!(
            MessageType::try_from(15).unwrap(),
            MessageType::GuildDiscoveryRequalified
        );
        assert_eq!(
            MessageType::try_from(16).unwrap(),
            MessageType::GuildDiscoveryGracePeriodInitialWarning
        );
        assert_eq!(
            MessageType::try_from(17).unwrap(),
            MessageType::GuildDiscoveryGracePeriodFinalWarning
        );
        assert_eq!(
            MessageType::try_from(18).unwrap(),
            MessageType::ThreadCreated
        );
        assert_eq!(MessageType::try_from(19).unwrap(), MessageType::Reply);
        assert_eq!(
            MessageType::try_from(20).unwrap(),
            MessageType::ChatInputCommand
        );
        assert_eq!(
            MessageType::try_from(21).unwrap(),
            MessageType::ThreadStarterMessage
        );
        assert_eq!(
            MessageType::try_from(22).unwrap(),
            MessageType::GuildInviteReminder
        );
        assert_eq!(
            MessageType::try_from(23).unwrap(),
            MessageType::ContextMenuCommand
        );
        assert_eq!(
            MessageType::try_from(24).unwrap(),
            MessageType::AutoModerationAction
        );
        assert_eq!(
            MessageType::try_from(250).unwrap_err(),
            ConversionError::MessageType(250)
        );
    }
}