twilight_model/gateway/payload/incoming/
voice_state_update.rs

1use crate::voice::VoiceState;
2use serde::{Deserialize, Serialize};
3use std::ops::{Deref, DerefMut};
4
5#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
6pub struct VoiceStateUpdate(pub VoiceState);
7
8impl Deref for VoiceStateUpdate {
9    type Target = VoiceState;
10
11    fn deref(&self) -> &Self::Target {
12        &self.0
13    }
14}
15
16impl DerefMut for VoiceStateUpdate {
17    fn deref_mut(&mut self) -> &mut Self::Target {
18        &mut self.0
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use super::{VoiceState, VoiceStateUpdate};
25    use crate::{
26        guild::{Member, MemberFlags},
27        id::Id,
28        test::image_hash,
29        user::User,
30        util::datetime::{Timestamp, TimestampParseError},
31    };
32    use serde_test::Token;
33    use std::str::FromStr;
34
35    #[test]
36    #[allow(clippy::too_many_lines)]
37    fn voice_state_update() {
38        let joined_at = Some(Timestamp::from_secs(1_632_072_645).expect("non zero"));
39        let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
40
41        let value = VoiceStateUpdate(VoiceState {
42            channel_id: None,
43            deaf: false,
44            guild_id: Some(Id::new(1)),
45            member: Some(Member {
46                avatar: None,
47                avatar_decoration_data: None,
48                banner: None,
49                communication_disabled_until: None,
50                deaf: false,
51                flags,
52                joined_at,
53                mute: false,
54                nick: None,
55                pending: false,
56                premium_since: None,
57                roles: vec![Id::new(4)],
58                user: User {
59                    id: Id::new(1),
60                    accent_color: None,
61                    avatar: None,
62                    avatar_decoration: None,
63                    avatar_decoration_data: None,
64                    banner: None,
65                    bot: false,
66                    discriminator: 909,
67                    global_name: Some("test".to_string()),
68                    name: "foo".to_string(),
69                    mfa_enabled: None,
70                    locale: None,
71                    verified: None,
72                    email: None,
73                    flags: None,
74                    premium_type: None,
75                    primary_guild: None,
76                    public_flags: None,
77                    system: None,
78                },
79            }),
80            mute: false,
81            self_deaf: false,
82            self_mute: false,
83            self_stream: false,
84            self_video: false,
85            session_id: "a".to_owned(),
86            suppress: false,
87            user_id: Id::new(1),
88            request_to_speak_timestamp: None,
89        });
90
91        serde_test::assert_tokens(
92            &value,
93            &[
94                Token::NewtypeStruct {
95                    name: "VoiceStateUpdate",
96                },
97                Token::Struct {
98                    name: "VoiceState",
99                    len: 13,
100                },
101                Token::Str("channel_id"),
102                Token::None,
103                Token::Str("deaf"),
104                Token::Bool(false),
105                Token::Str("guild_id"),
106                Token::Some,
107                Token::NewtypeStruct { name: "Id" },
108                Token::Str("1"),
109                Token::Str("member"),
110                Token::Some,
111                Token::Struct {
112                    name: "Member",
113                    len: 9,
114                },
115                Token::Str("communication_disabled_until"),
116                Token::None,
117                Token::Str("deaf"),
118                Token::Bool(false),
119                Token::Str("flags"),
120                Token::U64(flags.bits()),
121                Token::Str("joined_at"),
122                Token::Some,
123                Token::Str("2021-09-19T17:30:45.000000+00:00"),
124                Token::Str("mute"),
125                Token::Bool(false),
126                Token::Str("nick"),
127                Token::None,
128                Token::Str("pending"),
129                Token::Bool(false),
130                Token::Str("roles"),
131                Token::Seq { len: Some(1) },
132                Token::NewtypeStruct { name: "Id" },
133                Token::Str("4"),
134                Token::SeqEnd,
135                Token::Str("user"),
136                Token::Struct {
137                    name: "User",
138                    len: 10,
139                },
140                Token::Str("accent_color"),
141                Token::None,
142                Token::Str("avatar"),
143                Token::None,
144                Token::Str("avatar_decoration"),
145                Token::None,
146                Token::Str("avatar_decoration_data"),
147                Token::None,
148                Token::Str("banner"),
149                Token::None,
150                Token::Str("bot"),
151                Token::Bool(false),
152                Token::Str("discriminator"),
153                Token::Str("0909"),
154                Token::Str("global_name"),
155                Token::Some,
156                Token::Str("test"),
157                Token::Str("id"),
158                Token::NewtypeStruct { name: "Id" },
159                Token::Str("1"),
160                Token::Str("username"),
161                Token::Str("foo"),
162                Token::StructEnd,
163                Token::StructEnd,
164                Token::Str("mute"),
165                Token::Bool(false),
166                Token::Str("self_deaf"),
167                Token::Bool(false),
168                Token::Str("self_mute"),
169                Token::Bool(false),
170                Token::Str("self_stream"),
171                Token::Bool(false),
172                Token::Str("self_video"),
173                Token::Bool(false),
174                Token::Str("session_id"),
175                Token::Str("a"),
176                Token::Str("suppress"),
177                Token::Bool(false),
178                Token::Str("user_id"),
179                Token::NewtypeStruct { name: "Id" },
180                Token::Str("1"),
181                Token::Str("request_to_speak_timestamp"),
182                Token::None,
183                Token::StructEnd,
184            ],
185        );
186    }
187
188    #[test]
189    #[allow(clippy::too_many_lines)]
190    fn voice_state_update_deser_tokens() -> Result<(), TimestampParseError> {
191        let joined_at = Some(Timestamp::from_str("2016-12-08T18:41:21.954000+00:00")?);
192        let request_to_speak_timestamp = Timestamp::from_str("2021-03-31T18:45:31.297561+00:00")?;
193        let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
194
195        let value = VoiceStateUpdate(VoiceState {
196            channel_id: None,
197            deaf: false,
198            guild_id: Some(Id::new(999_999)),
199            member: Some(Member {
200                avatar: None,
201                avatar_decoration_data: None,
202                banner: None,
203                communication_disabled_until: None,
204                deaf: false,
205                flags,
206                joined_at,
207                mute: false,
208                nick: Some("Twilight".to_string()),
209                pending: false,
210                premium_since: None,
211                roles: vec![Id::new(123), Id::new(124)],
212                user: User {
213                    id: Id::new(1_234_123_123_123),
214                    accent_color: None,
215                    avatar: Some(image_hash::AVATAR),
216                    avatar_decoration: None,
217                    avatar_decoration_data: None,
218                    banner: None,
219                    bot: false,
220                    discriminator: 4242,
221                    global_name: Some("test".to_string()),
222                    name: "Twilight Sparkle".to_string(),
223                    mfa_enabled: None,
224                    locale: None,
225                    verified: None,
226                    email: None,
227                    flags: None,
228                    premium_type: None,
229                    primary_guild: None,
230                    public_flags: None,
231                    system: None,
232                },
233            }),
234            mute: false,
235            self_deaf: false,
236            self_mute: false,
237            self_stream: false,
238            self_video: false,
239            session_id: "asdasdas1da98da2b3ab3a".to_owned(),
240            suppress: false,
241            user_id: Id::new(123_213),
242            request_to_speak_timestamp: Some(request_to_speak_timestamp),
243        });
244
245        // Token stream here's `Member` has no `guild_id`, which deserializer
246        // must add.
247        // Lack of "guild_id" in real "member" means that de+ser does not
248        // reproduce original input (assert only `de`).
249        serde_test::assert_de_tokens(
250            &value,
251            &[
252                Token::NewtypeStruct {
253                    name: "VoiceStateUpdate",
254                },
255                Token::Struct {
256                    name: "VoiceState",
257                    len: 12,
258                },
259                Token::Str("channel_id"),
260                Token::None,
261                Token::Str("deaf"),
262                Token::Bool(false),
263                Token::Str("guild_id"),
264                Token::Some,
265                Token::NewtypeStruct { name: "Id" },
266                Token::Str("999999"),
267                Token::Str("member"),
268                Token::Some,
269                Token::Struct {
270                    name: "Member",
271                    len: 10,
272                },
273                Token::Str("communication_disabled_until"),
274                Token::None,
275                Token::Str("deaf"),
276                Token::Bool(false),
277                Token::Str("flags"),
278                Token::U64(flags.bits()),
279                Token::Str("joined_at"),
280                Token::Some,
281                Token::Str("2016-12-08T18:41:21.954000+00:00"),
282                Token::Str("mute"),
283                Token::Bool(false),
284                Token::Str("nick"),
285                Token::Some,
286                Token::Str("Twilight"),
287                Token::Str("pending"),
288                Token::Bool(false),
289                Token::Str("roles"),
290                Token::Seq { len: Some(2) },
291                Token::NewtypeStruct { name: "Id" },
292                Token::Str("123"),
293                Token::NewtypeStruct { name: "Id" },
294                Token::Str("124"),
295                Token::SeqEnd,
296                Token::Str("user"),
297                Token::Struct {
298                    name: "User",
299                    len: 8,
300                },
301                Token::Str("accent_color"),
302                Token::None,
303                Token::Str("avatar"),
304                Token::Some,
305                Token::Str(image_hash::AVATAR_INPUT),
306                Token::Str("banner"),
307                Token::None,
308                Token::Str("bot"),
309                Token::Bool(false),
310                Token::Str("discriminator"),
311                Token::Str("4242"),
312                Token::Str("global_name"),
313                Token::Some,
314                Token::Str("test"),
315                Token::Str("id"),
316                Token::NewtypeStruct { name: "Id" },
317                Token::Str("1234123123123"),
318                Token::Str("username"),
319                Token::Str("Twilight Sparkle"),
320                Token::StructEnd,
321                Token::StructEnd,
322                Token::Str("mute"),
323                Token::Bool(false),
324                Token::Str("self_deaf"),
325                Token::Bool(false),
326                Token::Str("self_mute"),
327                Token::Bool(false),
328                Token::Str("self_stream"),
329                Token::Bool(false),
330                Token::Str("self_video"),
331                Token::Bool(false),
332                Token::Str("session_id"),
333                Token::Str("asdasdas1da98da2b3ab3a"),
334                Token::Str("suppress"),
335                Token::Bool(false),
336                Token::Str("user_id"),
337                Token::NewtypeStruct { name: "Id" },
338                Token::Str("123213"),
339                Token::Str("request_to_speak_timestamp"),
340                Token::Some,
341                Token::Str("2021-03-31T18:45:31.297561+00:00"),
342                Token::StructEnd,
343            ],
344        );
345
346        Ok(())
347    }
348}