twilight_model/gateway/
reaction.rs

1use crate::{
2    channel::message::EmojiReactionType,
3    guild::Member,
4    id::{
5        Id,
6        marker::{ChannelMarker, GuildMarker, MessageMarker, UserMarker},
7    },
8    util::HexColor,
9};
10use serde::{Deserialize, Serialize};
11
12#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
13pub struct GatewayReaction {
14    /// True if this is a super-reaction.
15    pub burst: bool,
16    #[serde(default, skip_serializing_if = "Vec::is_empty")]
17    /// Colors used for super-reaction animation in hex format.
18    ///
19    /// This is only present when super-reactions are added.
20    pub burst_colors: Vec<HexColor>,
21    pub channel_id: Id<ChannelMarker>,
22    pub emoji: EmojiReactionType,
23    pub guild_id: Option<Id<GuildMarker>>,
24    pub member: Option<Member>,
25    /// ID of the user who authored the message which was reacted to.
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub message_author_id: Option<Id<UserMarker>>,
28    pub message_id: Id<MessageMarker>,
29    pub user_id: Id<UserMarker>,
30}
31
32#[cfg(test)]
33mod tests {
34    use super::GatewayReaction;
35    use crate::{
36        channel::message::EmojiReactionType,
37        guild::{Member, MemberFlags},
38        id::Id,
39        test::image_hash,
40        user::User,
41        util::{HexColor, Timestamp},
42    };
43    use serde_test::Token;
44    use std::str::FromStr;
45
46    #[allow(clippy::too_many_lines)]
47    #[test]
48    fn reaction_with_member() {
49        let joined_at = Some(Timestamp::from_str("2020-01-01T00:00:00.000000+00:00").unwrap());
50        let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
51        let burst_colors = ["#F200FF"];
52
53        let value = GatewayReaction {
54            burst: true,
55            burst_colors: burst_colors
56                .iter()
57                .map(|c| HexColor::from_str(c).unwrap())
58                .collect(),
59            channel_id: Id::new(2),
60            emoji: EmojiReactionType::Unicode {
61                name: "a".to_owned(),
62            },
63            guild_id: Some(Id::new(1)),
64            member: Some(Member {
65                avatar: None,
66                avatar_decoration_data: None,
67                banner: None,
68                communication_disabled_until: None,
69                deaf: false,
70                flags,
71                joined_at,
72                mute: false,
73                nick: Some("typing".to_owned()),
74                pending: false,
75                premium_since: None,
76                roles: vec![Id::new(5)],
77                user: User {
78                    accent_color: None,
79                    avatar: Some(image_hash::AVATAR),
80                    avatar_decoration: None,
81                    avatar_decoration_data: None,
82                    banner: None,
83                    bot: false,
84                    discriminator: 1,
85                    email: None,
86                    flags: None,
87                    global_name: Some("test".to_owned()),
88                    id: Id::new(4),
89                    locale: None,
90                    mfa_enabled: None,
91                    name: "test".to_owned(),
92                    premium_type: None,
93                    primary_guild: None,
94                    public_flags: None,
95                    system: None,
96                    verified: None,
97                },
98            }),
99            message_author_id: Some(Id::new(7)),
100            message_id: Id::new(3),
101            user_id: Id::new(4),
102        };
103
104        serde_test::assert_tokens(
105            &value,
106            &[
107                Token::Struct {
108                    name: "GatewayReaction",
109                    len: 9,
110                },
111                Token::Str("burst"),
112                Token::Bool(true),
113                Token::Str("burst_colors"),
114                Token::Seq { len: Some(1) },
115                Token::Str(burst_colors[0]),
116                Token::SeqEnd,
117                Token::Str("channel_id"),
118                Token::NewtypeStruct { name: "Id" },
119                Token::Str("2"),
120                Token::Str("emoji"),
121                Token::Struct {
122                    name: "EmojiReactionType",
123                    len: 1,
124                },
125                Token::Str("name"),
126                Token::Str("a"),
127                Token::StructEnd,
128                Token::Str("guild_id"),
129                Token::Some,
130                Token::NewtypeStruct { name: "Id" },
131                Token::Str("1"),
132                Token::Str("member"),
133                Token::Some,
134                Token::Struct {
135                    name: "Member",
136                    len: 9,
137                },
138                Token::Str("communication_disabled_until"),
139                Token::None,
140                Token::Str("deaf"),
141                Token::Bool(false),
142                Token::Str("flags"),
143                Token::U64(flags.bits()),
144                Token::Str("joined_at"),
145                Token::Some,
146                Token::Str("2020-01-01T00:00:00.000000+00:00"),
147                Token::Str("mute"),
148                Token::Bool(false),
149                Token::Str("nick"),
150                Token::Some,
151                Token::Str("typing"),
152                Token::Str("pending"),
153                Token::Bool(false),
154                Token::Str("roles"),
155                Token::Seq { len: Some(1) },
156                Token::NewtypeStruct { name: "Id" },
157                Token::Str("5"),
158                Token::SeqEnd,
159                Token::Str("user"),
160                Token::Struct {
161                    name: "User",
162                    len: 10,
163                },
164                Token::Str("accent_color"),
165                Token::None,
166                Token::Str("avatar"),
167                Token::Some,
168                Token::Str(image_hash::AVATAR_INPUT),
169                Token::Str("avatar_decoration"),
170                Token::None,
171                Token::Str("avatar_decoration_data"),
172                Token::None,
173                Token::Str("banner"),
174                Token::None,
175                Token::Str("bot"),
176                Token::Bool(false),
177                Token::Str("discriminator"),
178                Token::Str("0001"),
179                Token::Str("global_name"),
180                Token::Some,
181                Token::Str("test"),
182                Token::Str("id"),
183                Token::NewtypeStruct { name: "Id" },
184                Token::Str("4"),
185                Token::Str("username"),
186                Token::Str("test"),
187                Token::StructEnd,
188                Token::StructEnd,
189                Token::Str("message_author_id"),
190                Token::Some,
191                Token::NewtypeStruct { name: "Id" },
192                Token::Str("7"),
193                Token::Str("message_id"),
194                Token::NewtypeStruct { name: "Id" },
195                Token::Str("3"),
196                Token::Str("user_id"),
197                Token::NewtypeStruct { name: "Id" },
198                Token::Str("4"),
199                Token::StructEnd,
200            ],
201        );
202    }
203
204    #[test]
205    fn reaction_without_member() {
206        let value = GatewayReaction {
207            burst: false,
208            burst_colors: Vec::new(),
209            channel_id: Id::new(2),
210            emoji: EmojiReactionType::Unicode {
211                name: "a".to_owned(),
212            },
213            guild_id: None,
214            member: None,
215            message_id: Id::new(3),
216            message_author_id: Some(Id::new(7)),
217            user_id: Id::new(4),
218        };
219
220        serde_test::assert_tokens(
221            &value,
222            &[
223                Token::Struct {
224                    name: "GatewayReaction",
225                    len: 8,
226                },
227                Token::Str("burst"),
228                Token::Bool(false),
229                Token::Str("channel_id"),
230                Token::NewtypeStruct { name: "Id" },
231                Token::Str("2"),
232                Token::Str("emoji"),
233                Token::Struct {
234                    name: "EmojiReactionType",
235                    len: 1,
236                },
237                Token::Str("name"),
238                Token::Str("a"),
239                Token::StructEnd,
240                Token::Str("guild_id"),
241                Token::None,
242                Token::Str("member"),
243                Token::None,
244                Token::Str("message_author_id"),
245                Token::Some,
246                Token::NewtypeStruct { name: "Id" },
247                Token::Str("7"),
248                Token::Str("message_id"),
249                Token::NewtypeStruct { name: "Id" },
250                Token::Str("3"),
251                Token::Str("user_id"),
252                Token::NewtypeStruct { name: "Id" },
253                Token::Str("4"),
254                Token::StructEnd,
255            ],
256        );
257    }
258}