From 50fb20802336e6c08a161dc2862b381de3471fc6 Mon Sep 17 00:00:00 2001 From: kozabrada123 <“kozabrada123@users.noreply.github.com”> Date: Sat, 20 May 2023 08:39:02 +0200 Subject: [PATCH] Update dependencies, deserialize errors --- Cargo.toml | 6 ++--- src/api/types.rs | 57 ++++++++++++++++++++++++++++++++++++++++-------- src/gateway.rs | 4 ++-- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bac4455..b7c7207 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" [dependencies] tokio = {version = "1.27.0", features = ["rt", "macros", "rt-multi-thread"]} -serde = {version = "1.0.159", features = ["derive"]} -serde_json = {version= "1.0.95", features = ["raw_value"]} +serde = {version = "1.0.163", features = ["derive"]} +serde_json = {version= "1.0.96", features = ["raw_value"]} serde-aux = "4.2.0" reqwest = {version = "0.11.16", features = ["multipart"]} url = "2.3.1" @@ -15,6 +15,6 @@ chrono = {version = "0.4.24", features = ["serde"]} regex = "1.7.3" custom_error = "1.9.2" native-tls = "0.2.11" -tokio-tungstenite = {version = "0.18.0", features = ["native-tls"]} +tokio-tungstenite = {version = "0.19.0", features = ["native-tls"]} futures-util = "0.3.28" http = "0.2.9" \ No newline at end of file diff --git a/src/api/types.rs b/src/api/types.rs index 7d1b2e2..e660dcc 100644 --- a/src/api/types.rs +++ b/src/api/types.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_json::from_value; -use serde_aux::{field_attributes::deserialize_option_number_from_string, prelude::deserialize_string_from_number}; +use serde_aux::{field_attributes::deserialize_option_number_from_string, prelude::{deserialize_string_from_number, deserialize_number_from_string, deserialize_bool_from_anything}}; use crate::{api::limits::Limits, instance::Instance}; @@ -147,7 +147,7 @@ pub struct UnavailableGuild { #[derive(Serialize, Deserialize, Debug, Default, Clone)] pub struct Guild { pub id: String, - pub name: String, + pub name: Option, pub icon: Option, pub icon_hash: Option, pub splash: Option, @@ -165,7 +165,7 @@ pub struct Guild { pub explicit_content_filter: Option, pub roles: Vec, pub emojis: Vec, - pub features: Vec, + pub features: Option>, pub application_id: Option, pub system_channel_id: Option, pub system_channel_flags: Option, @@ -188,8 +188,8 @@ pub struct Guild { pub member_count: Option, pub presence_count: Option, pub welcome_screen: Option, - pub nsfw_level: u8, - pub nsfw: bool, + pub nsfw_level: Option, + pub nsfw: Option, pub stickers: Option>, pub premium_progress_bar_enabled: Option, pub joined_at: String, @@ -205,7 +205,7 @@ pub struct Guild { pub webhooks: Option>, pub mfa_level: Option, pub region: Option, - pub unavailable: bool, + pub unavailable: Option, pub parent: Option, } /// See https://docs.spacebar.chat/routes/#get-/guilds/-guild_id-/bans/-user- @@ -312,11 +312,30 @@ pub struct RoleObject { pub icon: Option, pub unicode_emoji: Option, pub position: u16, + #[serde(default)] + #[serde(deserialize_with = "deserialize_string_from_number")] pub permissions: String, pub managed: bool, pub mentionable: bool, - // to:do add role tags https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure - //pub tags: Option + pub tags: Option, +} + +#[derive(Serialize, Deserialize, Debug, Default, Clone)] +/// See https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure +pub struct RoleTags { + #[serde(default)] + #[serde(deserialize_with = "deserialize_option_number_from_string")] + pub bot_id: Option, + #[serde(default)] + #[serde(deserialize_with = "deserialize_option_number_from_string")] + pub integration_id: Option, + #[serde(default)] + #[serde(deserialize_with = "deserialize_option_number_from_string")] + pub subscription_listing_id: Option, + // These use the bad bool format, "Tags with type null represent booleans. They will be present and set to null if they are "true", and will be not present if they are "false"." + // premium_subscriber: bool, + // available_for_purchase: bool, + // guild_connections: bool, } #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)] @@ -670,6 +689,8 @@ pub struct Reaction { #[derive(Debug, Deserialize, Serialize, Default, Clone)] pub struct Emoji { + #[serde(default)] + #[serde(deserialize_with = "deserialize_option_number_from_string")] pub id: Option, pub name: Option, pub roles: Option>, @@ -818,9 +839,13 @@ pub struct Channel { #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Tag { + #[serde(default)] + #[serde(deserialize_with = "deserialize_number_from_string")] pub id: u64, pub name: String, pub moderated: bool, + #[serde(default)] + #[serde(deserialize_with = "deserialize_option_number_from_string")] pub emoji_id: Option, pub emoji_name: Option, } @@ -919,7 +944,9 @@ pub struct StageInstance { #[derive(Debug, Deserialize, Serialize, Clone)] pub struct DefaultReaction { - pub emoji_id: Option, + #[serde(default)] + #[serde(deserialize_with = "deserialize_option_number_from_string")] + pub emoji_id: Option, pub emoji_name: Option, } @@ -944,6 +971,8 @@ pub struct StickerItem { #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Sticker { + #[serde(default)] + #[serde(deserialize_with = "deserialize_number_from_string")] pub id: u64, pub pack_id: Option, pub name: String, @@ -954,6 +983,8 @@ pub struct Sticker { pub sticker_type: u8, pub format_type: u8, pub available: Option, + #[serde(default)] + #[serde(deserialize_with = "deserialize_option_number_from_string")] pub guild_id: Option, pub user: Option, pub sort_value: Option, @@ -994,11 +1025,19 @@ pub struct GatewayIdentifyPayload { } impl GatewayIdentifyPayload { + /// Creates an identify payload with the same default capabilities as the official client pub fn default_w_client_capabilities() -> Self { let mut def = Self::default(); def.capabilities = 8189; // Default capabilities for a client def } + + /// Creates an identify payload with all possible capabilities + pub fn default_w_all_capabilities() -> Self { + let mut def = Self::default(); + def.capabilities = i32::MAX; // Since discord uses bitwise for capabilities, this has almost every bit as 1, so all capabilities + def + } } impl WebSocketEvent for GatewayIdentifyPayload {} diff --git a/src/gateway.rs b/src/gateway.rs index 8c8ffa5..5677465 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -129,6 +129,7 @@ impl Gateway { let (ws_stream, _) = match connect_async_tls_with_config( &websocket_url, None, + false, Some(Connector::NativeTls( TlsConnector::builder().build().unwrap(), )), @@ -198,8 +199,7 @@ impl Gateway { println!("GW: Received {}..", gateway_payload_t); - let pretty_json = serde_json::to_string_pretty(&gateway_payload.clone().d.unwrap()).unwrap(); - println!("Event data dump: {}", pretty_json); + println!("Event data dump: {}", gateway_payload.d.clone().unwrap().get()); // See https://discord.com/developers/docs/topics/gateway-events#receive-events // "Some" of these are uncodumented