1use crate::{
2 guild::Member,
3 id::{
4 marker::{ChannelMarker, GuildMarker, UserMarker},
5 Id,
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 communication_disabled_until: None,
143 deaf: false,
144 flags,
145 joined_at,
146 mute: true,
147 nick: Some("twilight".to_owned()),
148 pending: false,
149 premium_since: Some(premium_since),
150 roles: Vec::new(),
151 user: User {
152 accent_color: None,
153 avatar: None,
154 avatar_decoration: None,
155 avatar_decoration_data: None,
156 banner: None,
157 bot: false,
158 discriminator: 1,
159 email: None,
160 flags: None,
161 global_name: Some("test".to_owned()),
162 id: Id::new(3),
163 locale: None,
164 mfa_enabled: None,
165 name: "twilight".to_owned(),
166 premium_type: None,
167 public_flags: None,
168 system: None,
169 verified: None,
170 },
171 }),
172 mute: true,
173 self_deaf: false,
174 self_mute: true,
175 self_stream: false,
176 self_video: false,
177 session_id: "a".to_owned(),
178 suppress: true,
179 user_id: Id::new(3),
180 request_to_speak_timestamp: Some(request_to_speak_timestamp),
181 };
182
183 serde_test::assert_tokens(
184 &value,
185 &[
186 Token::Struct {
187 name: "VoiceState",
188 len: 13,
189 },
190 Token::Str("channel_id"),
191 Token::Some,
192 Token::NewtypeStruct { name: "Id" },
193 Token::Str("1"),
194 Token::Str("deaf"),
195 Token::Bool(false),
196 Token::Str("guild_id"),
197 Token::Some,
198 Token::NewtypeStruct { name: "Id" },
199 Token::Str("2"),
200 Token::Str("member"),
201 Token::Some,
202 Token::Struct {
203 name: "Member",
204 len: 10,
205 },
206 Token::Str("communication_disabled_until"),
207 Token::None,
208 Token::Str("deaf"),
209 Token::Bool(false),
210 Token::Str("flags"),
211 Token::U64(flags.bits()),
212 Token::Str("joined_at"),
213 Token::Some,
214 Token::Str("2015-04-26T06:26:56.936000+00:00"),
215 Token::Str("mute"),
216 Token::Bool(true),
217 Token::Str("nick"),
218 Token::Some,
219 Token::Str("twilight"),
220 Token::Str("pending"),
221 Token::Bool(false),
222 Token::Str("premium_since"),
223 Token::Some,
224 Token::Str("2021-03-16T14:29:19.046000+00:00"),
225 Token::Str("roles"),
226 Token::Seq { len: Some(0) },
227 Token::SeqEnd,
228 Token::Str("user"),
229 Token::Struct {
230 name: "User",
231 len: 10,
232 },
233 Token::Str("accent_color"),
234 Token::None,
235 Token::Str("avatar"),
236 Token::None,
237 Token::Str("avatar_decoration"),
238 Token::None,
239 Token::Str("avatar_decoration_data"),
240 Token::None,
241 Token::Str("banner"),
242 Token::None,
243 Token::Str("bot"),
244 Token::Bool(false),
245 Token::Str("discriminator"),
246 Token::Str("0001"),
247 Token::Str("global_name"),
248 Token::Some,
249 Token::Str("test"),
250 Token::Str("id"),
251 Token::NewtypeStruct { name: "Id" },
252 Token::Str("3"),
253 Token::Str("username"),
254 Token::Str("twilight"),
255 Token::StructEnd,
256 Token::StructEnd,
257 Token::Str("mute"),
258 Token::Bool(true),
259 Token::Str("self_deaf"),
260 Token::Bool(false),
261 Token::Str("self_mute"),
262 Token::Bool(true),
263 Token::Str("self_stream"),
264 Token::Bool(false),
265 Token::Str("self_video"),
266 Token::Bool(false),
267 Token::Str("session_id"),
268 Token::Str("a"),
269 Token::Str("suppress"),
270 Token::Bool(true),
271 Token::Str("user_id"),
272 Token::NewtypeStruct { name: "Id" },
273 Token::Str("3"),
274 Token::Str("request_to_speak_timestamp"),
275 Token::Some,
276 Token::Str("2021-04-21T22:16:50.000000+00:00"),
277 Token::StructEnd,
278 ],
279 );
280
281 Ok(())
282 }
283}