1use std::fmt::{Display, Formatter, Result as FmtResult};
3
4use serde_json::{
5 Error as JsonError,
6 value::RawValue,
7};
8use serde_repr::{Deserialize_repr, Serialize_repr};
9
10use crate::{
11 guild::UnavailableGuild,
12 presence::{ClientActivity, ClientPresence},
13 Snowflake,
14 User
15};
16use crate::presence::Status;
17
18pub trait SendablePacket {
20 fn to_json(self) -> Result<String, JsonError>;
21 fn bytes(self) -> Result<Vec<u8>, JsonError>;
22}
23
24#[derive(Serialize, Deserialize, Debug)]
26pub struct GatewayBot {
27 pub url: String,
29 pub shards: usize,
31 pub session_start_limit: SessionStartLimit
33}
34#[derive(Serialize, Deserialize, Debug)]
36pub struct SessionStartLimit {
37 pub total: i32,
39 pub remaining: i32,
41 pub reset_after: i32,
43}
44
45#[derive(Serialize, Deserialize, Debug, Clone)]
47pub struct ReceivePacket {
48 pub op: Opcodes,
50 pub d: Box<RawValue>,
52 pub s: Option<u64>,
53 pub t: Option<GatewayEvent>
55}
56
57#[derive(Serialize, Deserialize, Debug)]
58pub struct SendPacket<T: SendablePacket> {
60 pub op: Opcodes,
62 pub d: T
64}
65
66#[derive(Serialize, Deserialize, Debug)]
68pub struct GatewayBrokerMessage {
69 pub guild_id: Snowflake,
71 pub packet: Box<RawValue>,
73}
74
75impl GatewayBrokerMessage {
76 pub fn new<T: SendablePacket>(guild_id: Snowflake, packet: T) -> Result<Self, JsonError> {
78 let raw = RawValue::from_string(packet.to_json()?)?;
79
80 Ok(Self {
81 guild_id,
82 packet: raw,
83 })
84 }
85 pub fn as_bytes(&self) -> Result<Vec<u8>, JsonError> {
87 let json = serde_json::to_string(self)?;
88
89 Ok(json.as_bytes().to_vec())
90 }
91}
92
93#[derive(Serialize, Deserialize, Debug, Clone)]
95pub struct IdentifyPacket {
96 pub token: String,
98 pub properties: IdentifyProperties,
100 #[serde(rename = "v")]
102 pub version: u8,
103 pub compress: bool,
105 pub large_threshold: i32,
107 pub shard: [usize; 2],
109 pub presence: Option<ClientPresence>
111}
112
113
114#[derive(Serialize, Deserialize, Debug, Clone)]
115pub struct IdentifyProperties {
116 #[serde(rename = "$os")]
118 pub os: String,
119 #[serde(rename = "$browser")]
121 pub browser: String,
122 #[serde(rename = "$device")]
124 pub device: String
125}
126
127#[derive(Serialize, Deserialize, Debug)]
129pub struct HelloPacket {
130 pub heartbeat_interval: u64,
132 pub _trace: Vec<String>
134}
135
136#[derive(Serialize, Deserialize, Debug, Clone)]
138pub struct ResumeSessionPacket {
139 pub session_id: String,
141 pub seq: u64,
143 pub token: String
145}
146#[derive(Serialize, Deserialize, Debug, Clone)]
148pub struct HeartbeatPacket {
149 pub seq: u64
151}
152
153#[derive(Serialize, Deserialize, Debug, Clone)]
154pub struct RequestGuildMembers {
156 pub guild_id: Snowflake,
158 pub query: String,
160 pub limit: i32
162}
163
164
165#[derive(Serialize, Deserialize, Debug, Clone)]
167pub struct UpdateVoiceState {
168 pub guild_id: Snowflake,
170 pub channel_id: Snowflake,
172 pub self_mute: bool,
174 pub self_deaf: bool
176}
177
178#[derive(Serialize, Deserialize, Debug, Clone, Default)]
180pub struct UpdateStatus {
181 pub since: Option<i32>,
183 pub game: Option<ClientActivity>,
185 pub status: Status,
187 pub afk: bool
189}
190
191impl UpdateStatus {
192 pub fn game(mut self, activity: ClientActivity) -> Self {
194 self.game = Some(activity);
195
196 self
197 }
198
199 pub fn status(mut self, status: Status) -> Self {
201 self.status = status;
202
203 self
204 }
205
206 pub fn afk(mut self, afk: bool) -> Self {
208 self.afk = afk;
209
210 self
211 }
212}
213
214impl SendablePacket for UpdateStatus {
215 fn to_json(self) -> Result<String, JsonError> {
216 serde_json::to_string(&SendPacket {
217 op: Opcodes::StatusUpdate,
218 d: self
219 })
220 }
221
222 fn bytes(self) -> Result<Vec<u8>, JsonError> {
223 let json = self.to_json()?;
224
225 Ok(json.as_bytes().to_vec())
226 }
227}
228
229
230impl SendablePacket for IdentifyPacket {
231 fn to_json(self) -> Result<String, JsonError> {
232 serde_json::to_string(&SendPacket {
233 op: Opcodes::Identify,
234 d: self
235 })
236 }
237
238 fn bytes(self) -> Result<Vec<u8>, JsonError> {
239 let json = self.to_json()?;
240
241 Ok(json.as_bytes().to_vec())
242 }
243}
244
245
246impl SendablePacket for UpdateVoiceState {
247 fn to_json(self) -> Result<String, JsonError> {
248 serde_json::to_string(&SendPacket {
249 op: Opcodes::VoiceStatusUpdate,
250 d: self,
251 })
252 }
253
254 fn bytes(self) -> Result<Vec<u8>, JsonError> {
255 let json = self.to_json()?;
256
257 Ok(json.as_bytes().to_vec())
258 }
259}
260impl SendablePacket for RequestGuildMembers {
261 fn to_json(self) -> Result<String, JsonError> {
262 serde_json::to_string(&SendPacket {
263 op: Opcodes::RequestGuildMembers,
264 d: self
265 })
266 }
267
268 fn bytes(self) -> Result<Vec<u8>, JsonError> {
269 let json = self.to_json()?;
270
271 Ok(json.as_bytes().to_vec())
272 }
273}
274
275impl SendablePacket for HeartbeatPacket {
276 fn to_json(self) -> Result<String, JsonError> {
277 serde_json::to_string(&SendPacket {
278 op: Opcodes::Heartbeat,
279 d: self
280 })
281 }
282
283 fn bytes(self) -> Result<Vec<u8>, JsonError> {
284 let json = self.to_json()?;
285
286 Ok(json.as_bytes().to_vec())
287 }
288}
289
290impl SendablePacket for ResumeSessionPacket {
291 fn to_json(self) -> Result<String, JsonError> {
292 serde_json::to_string(&SendPacket {
293 op: Opcodes::Resume,
294 d: self
295 })
296 }
297
298 fn bytes(self) -> Result<Vec<u8>, JsonError> {
299 let json = self.to_json()?;
300
301 Ok(json.as_bytes().to_vec())
302 }
303}
304
305#[derive(Deserialize, Serialize, Debug, Clone)]
308pub struct ReadyPacket {
309 pub v: i32,
311 pub user: User,
313 pub private_channels: [String; 0],
315 pub guilds: Vec<UnavailableGuild>,
318 pub session_id: String,
320 pub _trace: Vec<String>,
322 #[serde(default)]
324 pub shard: [u64; 2]
325}
326
327#[derive(Serialize, Deserialize, Debug, Clone)]
329pub struct ResumedPacket {
330 pub _trace: Vec<String>
332
333}
334#[derive(Debug, Deserialize, Serialize, Clone)]
335#[allow(non_camel_case_types)]
336pub enum GatewayEvent {
338 HELLO,
339 READY,
340 RESUMED,
341 INVALID_SESSION,
342 CHANNEL_CREATE,
343 CHANNEL_UPDATE,
344 CHANNEL_DELETE,
345 CHANNEL_PINS_UPDATE,
346 GUILD_CREATE,
347 GUILD_UPDATE,
348 GUILD_DELETE,
349 GUILD_BAN_ADD,
350 GUILD_BAN_REMOVE,
351 GUILD_EMOJIS_UPDATE,
352 GUILD_INTEGRATIONS_UPDATE,
353 GUILD_MEMBER_ADD,
354 GUILD_MEMBER_REMOVE,
355 GUILD_MEMBER_UPDATE,
356 GUILD_MEMBERS_CHUNK,
357 GUILD_ROLE_CREATE,
358 GUILD_ROLE_UPDATE,
359 GUILD_ROLE_DELETE,
360 MESSAGE_CREATE,
361 MESSAGE_UPDATE,
362 MESSAGE_DELETE,
363 MESSAGE_DELETE_BULK,
364 MESSAGE_REACTION_ADD,
365 MESSAGE_REACTION_REMOVE,
366 MESSAGE_REACTION_REMOVE_ALL,
367 PRESENCE_UPDATE,
368 PRESENCES_REPLACE,
369 TYPING_START,
370 USER_UPDATE,
371 VOICE_STATE_UPDATE,
372 VOICE_SERVER_UPDATE,
373 WEBHOOKS_UPDATE
374}
375
376impl Display for GatewayEvent {
377 fn fmt(&self, f: &mut Formatter) -> FmtResult {
378 write!(f, "{:?}", self)
379 }
380}
381#[derive(Serialize_repr, Deserialize_repr, Debug, Clone)]
383#[repr(u8)]
384pub enum Opcodes {
385 Dispatch,
387 Heartbeat,
389 Identify,
391 StatusUpdate,
393 VoiceStatusUpdate,
395 Resume = 6,
397 Reconnect,
399 RequestGuildMembers,
401 InvalidSession,
403 Hello,
405 HeartbeatAck
407}
408
409#[derive(Debug, Copy, Deserialize_repr, Clone)]
411#[repr(u16)]
412pub enum CloseCodes {
413 UnknownError = 4000,
415 UnknownOpcode,
417 DecodeError,
419 NotAuthenticated,
421 AuthenticationFailed,
423 AlreadyAuthenticated,
425 InvalidSeq,
427 Ratelimited,
429 SessionTimeout,
431 InvalidShard,
433 ShardingRequired,
435}