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 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 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}