twilight_model/gateway/
reaction.rs

1use crate::{
2    channel::message::EmojiReactionType,
3    guild::Member,
4    id::{
5        marker::{ChannelMarker, GuildMarker, MessageMarker, UserMarker},
6        Id,
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                communication_disabled_until: None,
67                deaf: false,
68                flags,
69                joined_at,
70                mute: false,
71                nick: Some("typing".to_owned()),
72                pending: false,
73                premium_since: None,
74                roles: vec![Id::new(5)],
75                user: User {
76                    accent_color: None,
77                    avatar: Some(image_hash::AVATAR),
78                    avatar_decoration: None,
79                    avatar_decoration_data: None,
80                    banner: None,
81                    bot: false,
82                    discriminator: 1,
83                    email: None,
84                    flags: None,
85                    global_name: Some("test".to_owned()),
86                    id: Id::new(4),
87                    locale: None,
88                    mfa_enabled: None,
89                    name: "test".to_owned(),
90                    premium_type: None,
91                    public_flags: None,
92                    system: None,
93                    verified: None,
94                },
95            }),
96            message_author_id: Some(Id::new(7)),
97            message_id: Id::new(3),
98            user_id: Id::new(4),
99        };
100
101        serde_test::assert_tokens(
102            &value,
103            &[
104                Token::Struct {
105                    name: "GatewayReaction",
106                    len: 9,
107                },
108                Token::Str("burst"),
109                Token::Bool(true),
110                Token::Str("burst_colors"),
111                Token::Seq { len: Some(1) },
112                Token::Str(burst_colors[0]),
113                Token::SeqEnd,
114                Token::Str("channel_id"),
115                Token::NewtypeStruct { name: "Id" },
116                Token::Str("2"),
117                Token::Str("emoji"),
118                Token::Struct {
119                    name: "EmojiReactionType",
120                    len: 1,
121                },
122                Token::Str("name"),
123                Token::Str("a"),
124                Token::StructEnd,
125                Token::Str("guild_id"),
126                Token::Some,
127                Token::NewtypeStruct { name: "Id" },
128                Token::Str("1"),
129                Token::Str("member"),
130                Token::Some,
131                Token::Struct {
132                    name: "Member",
133                    len: 9,
134                },
135                Token::Str("communication_disabled_until"),
136                Token::None,
137                Token::Str("deaf"),
138                Token::Bool(false),
139                Token::Str("flags"),
140                Token::U64(flags.bits()),
141                Token::Str("joined_at"),
142                Token::Some,
143                Token::Str("2020-01-01T00:00:00.000000+00:00"),
144                Token::Str("mute"),
145                Token::Bool(false),
146                Token::Str("nick"),
147                Token::Some,
148                Token::Str("typing"),
149                Token::Str("pending"),
150                Token::Bool(false),
151                Token::Str("roles"),
152                Token::Seq { len: Some(1) },
153                Token::NewtypeStruct { name: "Id" },
154                Token::Str("5"),
155                Token::SeqEnd,
156                Token::Str("user"),
157                Token::Struct {
158                    name: "User",
159                    len: 10,
160                },
161                Token::Str("accent_color"),
162                Token::None,
163                Token::Str("avatar"),
164                Token::Some,
165                Token::Str(image_hash::AVATAR_INPUT),
166                Token::Str("avatar_decoration"),
167                Token::None,
168                Token::Str("avatar_decoration_data"),
169                Token::None,
170                Token::Str("banner"),
171                Token::None,
172                Token::Str("bot"),
173                Token::Bool(false),
174                Token::Str("discriminator"),
175                Token::Str("0001"),
176                Token::Str("global_name"),
177                Token::Some,
178                Token::Str("test"),
179                Token::Str("id"),
180                Token::NewtypeStruct { name: "Id" },
181                Token::Str("4"),
182                Token::Str("username"),
183                Token::Str("test"),
184                Token::StructEnd,
185                Token::StructEnd,
186                Token::Str("message_author_id"),
187                Token::Some,
188                Token::NewtypeStruct { name: "Id" },
189                Token::Str("7"),
190                Token::Str("message_id"),
191                Token::NewtypeStruct { name: "Id" },
192                Token::Str("3"),
193                Token::Str("user_id"),
194                Token::NewtypeStruct { name: "Id" },
195                Token::Str("4"),
196                Token::StructEnd,
197            ],
198        );
199    }
200
201    #[test]
202    fn reaction_without_member() {
203        let value = GatewayReaction {
204            burst: false,
205            burst_colors: Vec::new(),
206            channel_id: Id::new(2),
207            emoji: EmojiReactionType::Unicode {
208                name: "a".to_owned(),
209            },
210            guild_id: None,
211            member: None,
212            message_id: Id::new(3),
213            message_author_id: Some(Id::new(7)),
214            user_id: Id::new(4),
215        };
216
217        serde_test::assert_tokens(
218            &value,
219            &[
220                Token::Struct {
221                    name: "GatewayReaction",
222                    len: 8,
223                },
224                Token::Str("burst"),
225                Token::Bool(false),
226                Token::Str("channel_id"),
227                Token::NewtypeStruct { name: "Id" },
228                Token::Str("2"),
229                Token::Str("emoji"),
230                Token::Struct {
231                    name: "EmojiReactionType",
232                    len: 1,
233                },
234                Token::Str("name"),
235                Token::Str("a"),
236                Token::StructEnd,
237                Token::Str("guild_id"),
238                Token::None,
239                Token::Str("member"),
240                Token::None,
241                Token::Str("message_author_id"),
242                Token::Some,
243                Token::NewtypeStruct { name: "Id" },
244                Token::Str("7"),
245                Token::Str("message_id"),
246                Token::NewtypeStruct { name: "Id" },
247                Token::Str("3"),
248                Token::Str("user_id"),
249                Token::NewtypeStruct { name: "Id" },
250                Token::Str("4"),
251                Token::StructEnd,
252            ],
253        );
254    }
255}