1use crate::{
2 guild::Member,
3 id::{
4 Id,
5 marker::{ChannelMarker, GuildMarker, UserMarker},
6 },
7 util::Timestamp,
8};
9use serde::{Deserialize, Serialize};
10
11#[allow(clippy::struct_excessive_bools)]
13#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
14pub struct VoiceState {
15 pub channel_id: Option<Id<ChannelMarker>>,
19 pub deaf: bool,
21 #[serde(skip_serializing_if = "Option::is_none")]
23 pub guild_id: Option<Id<GuildMarker>>,
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub member: Option<Member>,
27 pub mute: bool,
29 pub self_deaf: bool,
31 pub self_mute: bool,
33 #[serde(default)]
35 pub self_stream: bool,
36 pub self_video: bool,
38 pub session_id: String,
42 pub suppress: bool,
46 pub user_id: Id<UserMarker>,
48 pub request_to_speak_timestamp: Option<Timestamp>,
55}
56
57#[cfg(test)]
58mod tests {
59 use super::VoiceState;
60 use crate::{
61 guild::{Member, MemberFlags},
62 id::Id,
63 user::User,
64 util::datetime::{Timestamp, TimestampParseError},
65 };
66 use serde_test::Token;
67 use std::str::FromStr;
68
69 #[test]
70 fn voice_state() {
71 let value = VoiceState {
72 channel_id: Some(Id::new(1)),
73 deaf: false,
74 guild_id: Some(Id::new(2)),
75 member: None,
76 mute: true,
77 self_deaf: false,
78 self_mute: true,
79 self_stream: false,
80 self_video: false,
81 session_id: "a".to_owned(),
82 suppress: true,
83 user_id: Id::new(3),
84 request_to_speak_timestamp: None,
85 };
86
87 serde_test::assert_tokens(
88 &value,
89 &[
90 Token::Struct {
91 name: "VoiceState",
92 len: 12,
93 },
94 Token::Str("channel_id"),
95 Token::Some,
96 Token::NewtypeStruct { name: "Id" },
97 Token::Str("1"),
98 Token::Str("deaf"),
99 Token::Bool(false),
100 Token::Str("guild_id"),
101 Token::Some,
102 Token::NewtypeStruct { name: "Id" },
103 Token::Str("2"),
104 Token::Str("mute"),
105 Token::Bool(true),
106 Token::Str("self_deaf"),
107 Token::Bool(false),
108 Token::Str("self_mute"),
109 Token::Bool(true),
110 Token::Str("self_stream"),
111 Token::Bool(false),
112 Token::Str("self_video"),
113 Token::Bool(false),
114 Token::Str("session_id"),
115 Token::Str("a"),
116 Token::Str("suppress"),
117 Token::Bool(true),
118 Token::Str("user_id"),
119 Token::NewtypeStruct { name: "Id" },
120 Token::Str("3"),
121 Token::Str("request_to_speak_timestamp"),
122 Token::None,
123 Token::StructEnd,
124 ],
125 );
126 }
127
128 #[allow(clippy::too_many_lines)]
129 #[test]
130 fn voice_state_complete() -> Result<(), TimestampParseError> {
131 let joined_at = Some(Timestamp::from_str("2015-04-26T06:26:56.936000+00:00")?);
132 let premium_since = Timestamp::from_str("2021-03-16T14:29:19.046000+00:00")?;
133 let request_to_speak_timestamp = Timestamp::from_str("2021-04-21T22:16:50.000000+00:00")?;
134 let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
135
136 let value = VoiceState {
137 channel_id: Some(Id::new(1)),
138 deaf: false,
139 guild_id: Some(Id::new(2)),
140 member: Some(Member {
141 avatar: None,
142 avatar_decoration_data: None,
143 banner: None,
144 communication_disabled_until: None,
145 deaf: false,
146 flags,
147 joined_at,
148 mute: true,
149 nick: Some("twilight".to_owned()),
150 pending: false,
151 premium_since: Some(premium_since),
152 roles: Vec::new(),
153 user: User {
154 accent_color: None,
155 avatar: None,
156 avatar_decoration: None,
157 avatar_decoration_data: None,
158 banner: None,
159 bot: false,
160 discriminator: 1,
161 email: None,
162 flags: None,
163 global_name: Some("test".to_owned()),
164 id: Id::new(3),
165 locale: None,
166 mfa_enabled: None,
167 name: "twilight".to_owned(),
168 premium_type: None,
169 primary_guild: None,
170 public_flags: None,
171 system: None,
172 verified: None,
173 },
174 }),
175 mute: true,
176 self_deaf: false,
177 self_mute: true,
178 self_stream: false,
179 self_video: false,
180 session_id: "a".to_owned(),
181 suppress: true,
182 user_id: Id::new(3),
183 request_to_speak_timestamp: Some(request_to_speak_timestamp),
184 };
185
186 serde_test::assert_tokens(
187 &value,
188 &[
189 Token::Struct {
190 name: "VoiceState",
191 len: 13,
192 },
193 Token::Str("channel_id"),
194 Token::Some,
195 Token::NewtypeStruct { name: "Id" },
196 Token::Str("1"),
197 Token::Str("deaf"),
198 Token::Bool(false),
199 Token::Str("guild_id"),
200 Token::Some,
201 Token::NewtypeStruct { name: "Id" },
202 Token::Str("2"),
203 Token::Str("member"),
204 Token::Some,
205 Token::Struct {
206 name: "Member",
207 len: 10,
208 },
209 Token::Str("communication_disabled_until"),
210 Token::None,
211 Token::Str("deaf"),
212 Token::Bool(false),
213 Token::Str("flags"),
214 Token::U64(flags.bits()),
215 Token::Str("joined_at"),
216 Token::Some,
217 Token::Str("2015-04-26T06:26:56.936000+00:00"),
218 Token::Str("mute"),
219 Token::Bool(true),
220 Token::Str("nick"),
221 Token::Some,
222 Token::Str("twilight"),
223 Token::Str("pending"),
224 Token::Bool(false),
225 Token::Str("premium_since"),
226 Token::Some,
227 Token::Str("2021-03-16T14:29:19.046000+00:00"),
228 Token::Str("roles"),
229 Token::Seq { len: Some(0) },
230 Token::SeqEnd,
231 Token::Str("user"),
232 Token::Struct {
233 name: "User",
234 len: 10,
235 },
236 Token::Str("accent_color"),
237 Token::None,
238 Token::Str("avatar"),
239 Token::None,
240 Token::Str("avatar_decoration"),
241 Token::None,
242 Token::Str("avatar_decoration_data"),
243 Token::None,
244 Token::Str("banner"),
245 Token::None,
246 Token::Str("bot"),
247 Token::Bool(false),
248 Token::Str("discriminator"),
249 Token::Str("0001"),
250 Token::Str("global_name"),
251 Token::Some,
252 Token::Str("test"),
253 Token::Str("id"),
254 Token::NewtypeStruct { name: "Id" },
255 Token::Str("3"),
256 Token::Str("username"),
257 Token::Str("twilight"),
258 Token::StructEnd,
259 Token::StructEnd,
260 Token::Str("mute"),
261 Token::Bool(true),
262 Token::Str("self_deaf"),
263 Token::Bool(false),
264 Token::Str("self_mute"),
265 Token::Bool(true),
266 Token::Str("self_stream"),
267 Token::Bool(false),
268 Token::Str("self_video"),
269 Token::Bool(false),
270 Token::Str("session_id"),
271 Token::Str("a"),
272 Token::Str("suppress"),
273 Token::Bool(true),
274 Token::Str("user_id"),
275 Token::NewtypeStruct { name: "Id" },
276 Token::Str("3"),
277 Token::Str("request_to_speak_timestamp"),
278 Token::Some,
279 Token::Str("2021-04-21T22:16:50.000000+00:00"),
280 Token::StructEnd,
281 ],
282 );
283
284 Ok(())
285 }
286}