Skip to main content

twilight_model/gateway/
capabilities.rs

1use bitflags::bitflags;
2use serde::{
3    de::{Deserialize, Deserializer},
4    ser::{Serialize, Serializer},
5};
6
7bitflags! {
8    /// Gateway capabilities.
9    ///
10    /// Developers may specify capabilities when connecting to the gateway.
11    /// Capabilities allow applications to opt-in to gateway behavior. To
12    /// specify multiple capabilities, create a union using the `|` operator. See
13    /// [Discord Docs/Capabilities].
14    ///
15    /// [Discord Docs/Capabilities]: https://discord.com/developers/docs/topics/gateway#identify-gateway-capabilities
16    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
17    pub struct Capabilities: u64 {
18        /// Opts the client into receiving obfuscated channel metadata over the
19        /// Gateway for channels it can't view.
20        ///
21        /// Discord plans to fully roll out Channel Obfuscation for all users on
22        /// November 16th, 2026, at which point specifying this capability would
23        /// have no effect.
24        ///
25        /// See [Discord Docs/Channel Obfuscation].
26        ///
27        /// [Discord Docs/Channel Obfuscation]: https://docs.discord.com/developers/resources/channel#channel-object-obfuscated-channels
28        const CHANNEL_OBFUSCATION = 1 << 15;
29    }
30}
31
32impl<'de> Deserialize<'de> for Capabilities {
33    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
34        Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?))
35    }
36}
37
38impl Serialize for Capabilities {
39    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
40    where
41        S: Serializer,
42    {
43        serializer.serialize_u64(self.bits())
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::Capabilities;
50    use serde::{Deserialize, Serialize};
51    use serde_test::Token;
52    use static_assertions::{assert_impl_all, const_assert_eq};
53    use std::{
54        fmt::{Binary, Debug, LowerHex, Octal, UpperHex},
55        hash::Hash,
56        ops::{
57            BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign,
58        },
59    };
60
61    assert_impl_all!(
62        Capabilities: Binary,
63        BitAnd,
64        BitAndAssign,
65        BitOr,
66        BitOrAssign,
67        BitXor,
68        BitXorAssign,
69        Clone,
70        Copy,
71        Debug,
72        Deserialize<'static>,
73        Eq,
74        Extend<Capabilities>,
75        FromIterator<Capabilities>,
76        Hash,
77        LowerHex,
78        Not,
79        Octal,
80        PartialEq,
81        Send,
82        Serialize,
83        Sub,
84        SubAssign,
85        Sync,
86        UpperHex
87    );
88    const_assert_eq!(Capabilities::CHANNEL_OBFUSCATION.bits(), 1 << 15);
89
90    #[test]
91    fn serde() {
92        serde_test::assert_tokens(
93            &Capabilities::CHANNEL_OBFUSCATION,
94            &[Token::U64(Capabilities::CHANNEL_OBFUSCATION.bits())],
95        );
96        // Deserialization truncates unknown bits.
97        serde_test::assert_de_tokens(&Capabilities::empty(), &[Token::U64(1 << 63)]);
98    }
99}