twilight_cache_inmemory/model/
voice_state.rs

1use serde::Serialize;
2use twilight_model::{
3    id::{
4        marker::{ChannelMarker, GuildMarker, UserMarker},
5        Id,
6    },
7    util::Timestamp,
8    voice::VoiceState,
9};
10
11use crate::CacheableVoiceState;
12
13/// Represents a cached [`VoiceState`].
14///
15/// [`VoiceState`]: twilight_model::voice::VoiceState
16#[allow(clippy::struct_excessive_bools)]
17#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
18pub struct CachedVoiceState {
19    channel_id: Id<ChannelMarker>,
20    deaf: bool,
21    guild_id: Id<GuildMarker>,
22    mute: bool,
23    request_to_speak_timestamp: Option<Timestamp>,
24    self_deaf: bool,
25    self_mute: bool,
26    self_stream: bool,
27    self_video: bool,
28    session_id: String,
29    suppress: bool,
30    user_id: Id<UserMarker>,
31}
32
33impl CachedVoiceState {
34    /// ID of the channel that this user is connected to.
35    pub const fn channel_id(&self) -> Id<ChannelMarker> {
36        self.channel_id
37    }
38
39    /// Whether the user is deafened.
40    pub const fn deaf(&self) -> bool {
41        self.deaf
42    }
43
44    /// ID of the guild that this user is connected in, if there is one.
45    pub const fn guild_id(&self) -> Id<GuildMarker> {
46        self.guild_id
47    }
48
49    /// Whether the user is muted.
50    pub const fn mute(&self) -> bool {
51        self.mute
52    }
53
54    /// Timestamp of when the user requested to speak.
55    pub const fn request_to_speak_timestamp(&self) -> Option<Timestamp> {
56        self.request_to_speak_timestamp
57    }
58
59    /// Whether the user has deafened themself.
60    pub const fn self_deaf(&self) -> bool {
61        self.self_deaf
62    }
63
64    /// Whether the user has muted themself.
65    pub const fn self_mute(&self) -> bool {
66        self.self_mute
67    }
68
69    /// Whether the user is streaming via "Go Live".
70    pub const fn self_stream(&self) -> bool {
71        self.self_stream
72    }
73
74    /// Whether the user's camera is enabled.
75    pub const fn self_video(&self) -> bool {
76        self.self_video
77    }
78
79    /// Session ID.
80    #[allow(clippy::missing_const_for_fn)]
81    pub fn session_id(&self) -> &str {
82        &self.session_id
83    }
84
85    /// Whether this user is muted by the current user.
86    pub const fn suppress(&self) -> bool {
87        self.suppress
88    }
89
90    /// ID of the user.
91    pub const fn user_id(&self) -> Id<UserMarker> {
92        self.user_id
93    }
94}
95
96impl From<(Id<ChannelMarker>, Id<GuildMarker>, VoiceState)> for CachedVoiceState {
97    fn from(
98        (channel_id, guild_id, voice_state): (Id<ChannelMarker>, Id<GuildMarker>, VoiceState),
99    ) -> Self {
100        // Reasons for dropping fields:
101        //
102        // - `channel_id`: provided as a function parameter
103        // - `guild_id`: provided as a function parameter
104        // - `member`: we have the user's ID from the `user_id` field
105        let VoiceState {
106            channel_id: _,
107            deaf,
108            guild_id: _,
109            member: _,
110            mute,
111            self_deaf,
112            self_mute,
113            self_stream,
114            self_video,
115            session_id,
116            suppress,
117            user_id,
118            request_to_speak_timestamp,
119        } = voice_state;
120
121        Self {
122            channel_id,
123            deaf,
124            guild_id,
125            mute,
126            request_to_speak_timestamp,
127            self_deaf,
128            self_mute,
129            self_stream,
130            self_video,
131            session_id,
132            suppress,
133            user_id,
134        }
135    }
136}
137
138impl PartialEq<VoiceState> for CachedVoiceState {
139    fn eq(&self, other: &VoiceState) -> bool {
140        Some(self.channel_id) == other.channel_id
141            && self.deaf == other.deaf
142            && Some(self.guild_id) == other.guild_id
143            && self.mute == other.mute
144            && self.request_to_speak_timestamp == other.request_to_speak_timestamp
145            && self.self_deaf == other.self_deaf
146            && self.self_mute == other.self_mute
147            && self.self_stream == other.self_stream
148            && self.self_video == other.self_video
149            && self.session_id == other.session_id
150            && self.suppress == other.suppress
151            && self.user_id == other.user_id
152    }
153}
154
155impl CacheableVoiceState for CachedVoiceState {
156    fn channel_id(&self) -> Id<ChannelMarker> {
157        self.channel_id
158    }
159}
160
161#[cfg(test)]
162mod tests {
163    use super::CachedVoiceState;
164    use crate::test;
165    use serde::Serialize;
166    use static_assertions::{assert_fields, assert_impl_all};
167    use std::fmt::Debug;
168    use twilight_model::{
169        id::{
170            marker::{ChannelMarker, GuildMarker, UserMarker},
171            Id,
172        },
173        voice::VoiceState,
174    };
175
176    assert_fields!(
177        CachedVoiceState: channel_id,
178        deaf,
179        guild_id,
180        mute,
181        request_to_speak_timestamp,
182        self_deaf,
183        self_mute,
184        self_stream,
185        self_video,
186        session_id,
187        suppress,
188        user_id
189    );
190    assert_impl_all!(
191        CachedVoiceState: Clone,
192        Debug,
193        Eq,
194        PartialEq,
195        PartialEq<VoiceState>,
196        Serialize,
197    );
198
199    const CHANNEL_ID: Id<ChannelMarker> = Id::new(1);
200    const GUILD_ID: Id<GuildMarker> = Id::new(2);
201    const USER_ID: Id<UserMarker> = Id::new(3);
202
203    #[test]
204    fn eq() {
205        let voice_state = test::voice_state(GUILD_ID, Some(CHANNEL_ID), USER_ID);
206        let cached = CachedVoiceState::from((CHANNEL_ID, GUILD_ID, voice_state.clone()));
207
208        assert_eq!(cached, voice_state);
209    }
210
211    #[test]
212    fn getters() {
213        let voice_state = test::voice_state(GUILD_ID, Some(CHANNEL_ID), USER_ID);
214        let cached = CachedVoiceState::from((CHANNEL_ID, GUILD_ID, voice_state.clone()));
215
216        assert_eq!(Some(cached.channel_id()), voice_state.channel_id);
217        assert_eq!(cached.deaf(), voice_state.deaf);
218        assert_eq!(Some(cached.guild_id()), voice_state.guild_id);
219        assert_eq!(cached.mute(), voice_state.mute);
220        assert_eq!(
221            cached.request_to_speak_timestamp(),
222            voice_state.request_to_speak_timestamp
223        );
224        assert_eq!(cached.self_deaf(), voice_state.self_deaf);
225        assert_eq!(cached.self_mute(), voice_state.self_mute);
226        assert_eq!(cached.self_stream(), voice_state.self_stream);
227        assert_eq!(cached.self_video(), voice_state.self_video);
228        assert_eq!(cached.session_id(), voice_state.session_id);
229        assert_eq!(cached.suppress(), voice_state.suppress);
230        assert_eq!(cached.user_id(), voice_state.user_id);
231    }
232}