1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! Sealed Command trait to denote what can be provided to [`Shard::command`].
//!
//! [`Shard::command`]: crate::Shard::command

use twilight_model::gateway::payload::outgoing::{
    RequestGuildMembers, UpdatePresence, UpdateVoiceState,
};

mod private {
    //! Private module to provide a sealed trait depended on by [`Command`],
    //! disallowing consumers from implementing it.
    //!
    //! [`Command`]: super::Command

    use serde::Serialize;
    use twilight_model::gateway::payload::outgoing::{
        RequestGuildMembers, UpdatePresence, UpdateVoiceState,
    };

    /// Sealed trait to prevent users from implementing the Command trait.
    pub trait Sealed: Serialize {}

    impl Sealed for RequestGuildMembers {}
    impl Sealed for UpdatePresence {}
    impl Sealed for UpdateVoiceState {}
}

/// Trait marker denoting what can be provided to [`Shard::command`].
///
/// This trait exists to make it easier to determine what commands can be sent
/// to the Discord Gateway API.
///
/// This is deliberately not implemented for [`Heartbeat`], [`Identify`], and
/// [`Resume`] due to shards automatically sending them as necessary.
///
/// To send an arbitrary command to the Discord Gateway API then [`Shard::send`]
/// may be used.
///
/// [`Heartbeat`]: twilight_model::gateway::payload::outgoing::Heartbeat
/// [`Identify`]: twilight_model::gateway::payload::outgoing::Identify
/// [`Resume`]: twilight_model::gateway::payload::outgoing::Resume
/// [`Shard::command`]: crate::Shard::command
/// [`Shard::send`]: crate::Shard::send
pub trait Command: private::Sealed {}

impl Command for RequestGuildMembers {}
impl Command for UpdatePresence {}
impl Command for UpdateVoiceState {}

#[cfg(test)]
mod tests {
    use super::Command;
    use static_assertions::assert_impl_all;
    use twilight_model::gateway::payload::outgoing::{
        RequestGuildMembers, UpdatePresence, UpdateVoiceState,
    };

    assert_impl_all!(RequestGuildMembers: Command);
    assert_impl_all!(UpdatePresence: Command);
    assert_impl_all!(UpdateVoiceState: Command);
}