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