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 pub burst: bool,
16 #[serde(default, skip_serializing_if = "Vec::is_empty")]
17 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 #[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}