titanium_gateway/opcode.rs
1//! Discord Gateway opcodes.
2//!
3//! Opcodes define the type of payload being sent or received over the Gateway WebSocket.
4
5use serde_repr::{Deserialize_repr, Serialize_repr};
6
7/// Discord Gateway operation codes.
8///
9/// See: <https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes>
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)]
11#[repr(u8)]
12pub enum OpCode {
13 /// Dispatch - An event was dispatched.
14 /// Direction: Receive
15 Dispatch = 0,
16
17 /// Heartbeat - Keep the connection alive.
18 /// Direction: Send/Receive
19 Heartbeat = 1,
20
21 /// Identify - Start a new session.
22 /// Direction: Send
23 Identify = 2,
24
25 /// Presence Update - Update the client's presence.
26 /// Direction: Send
27 PresenceUpdate = 3,
28
29 /// Voice State Update - Join/leave/move between voice channels.
30 /// Direction: Send
31 VoiceStateUpdate = 4,
32
33 /// Resume - Resume a previous session.
34 /// Direction: Send
35 Resume = 6,
36
37 /// Reconnect - Server requested a reconnect.
38 /// Direction: Receive
39 Reconnect = 7,
40
41 /// Request Guild Members - Request guild member chunks.
42 /// Direction: Send
43 RequestGuildMembers = 8,
44
45 /// Invalid Session - Session has been invalidated.
46 /// Direction: Receive
47 InvalidSession = 9,
48
49 /// Hello - Sent after connecting, contains heartbeat interval.
50 /// Direction: Receive
51 Hello = 10,
52
53 /// Heartbeat ACK - Acknowledgment of heartbeat received.
54 /// Direction: Receive
55 HeartbeatAck = 11,
56
57 /// Request Soundboard Sounds - Request soundboard sounds (API v10+).
58 /// Direction: Send
59 RequestSoundboardSounds = 31,
60}
61
62impl OpCode {
63 /// Returns whether this opcode is only received (not sent).
64 pub const fn is_receive_only(self) -> bool {
65 matches!(
66 self,
67 OpCode::Dispatch
68 | OpCode::Reconnect
69 | OpCode::InvalidSession
70 | OpCode::Hello
71 | OpCode::HeartbeatAck
72 )
73 }
74
75 /// Returns whether this opcode is only sent (not received).
76 pub const fn is_send_only(self) -> bool {
77 matches!(
78 self,
79 OpCode::Identify
80 | OpCode::PresenceUpdate
81 | OpCode::VoiceStateUpdate
82 | OpCode::Resume
83 | OpCode::RequestGuildMembers
84 | OpCode::RequestSoundboardSounds
85 )
86 }
87
88 /// Returns whether this opcode can be both sent and received.
89 pub const fn is_bidirectional(self) -> bool {
90 matches!(self, OpCode::Heartbeat)
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_opcode_serialization() {
100 let json = serde_json::to_string(&OpCode::Hello).unwrap();
101 assert_eq!(json, "10");
102
103 let opcode: OpCode = serde_json::from_str("10").unwrap();
104 assert_eq!(opcode, OpCode::Hello);
105 }
106
107 #[test]
108 fn test_opcode_direction() {
109 assert!(OpCode::Dispatch.is_receive_only());
110 assert!(OpCode::Identify.is_send_only());
111 assert!(OpCode::Heartbeat.is_bidirectional());
112 }
113}