From 192f12d89283765c48ea8a49db64fbd459c3aec9 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 10 Jul 2023 16:59:00 +0200 Subject: [PATCH 001/237] /* -> /// --- src/api/channels/messages.rs | 41 +++++++++++++++----------------- src/api/channels/reactions.rs | 4 +--- src/api/users/users.rs | 18 +++++++------- src/instance.rs | 6 ++--- src/types/entities/attachment.rs | 6 +---- 5 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index dbffaa8..c46409f 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -9,17 +9,15 @@ use crate::ratelimiter::ChorusRequest; use crate::types::{Message, MessageSendSchema, PartialDiscordFileAttachment, Snowflake}; impl Message { - /** - Sends a message to the Spacebar server. - # Arguments - * `url_api` - The URL of the Spacebar server's API. - * `message` - The [`Message`] that will be sent to the Spacebar server. - * `limits_user` - The [`Limits`] of the user. - * `limits_instance` - The [`Limits`] of the instance. - * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. - # Errors - * [`ChorusLibError`] - If the message cannot be sent. - */ + /// Sends a message to the Spacebar server. + /// # Arguments + /// * `url_api` - The URL of the Spacebar server's API. + /// * `message` - The [`Message`] that will be sent to the Spacebar server. + /// * `limits_user` - The [`Limits`] of the user. + /// * `limits_instance` - The [`Limits`] of the instance. + /// * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. + /// # Errors + /// * [`ChorusLibError`] - If the message cannot be sent. pub async fn send( user: &mut UserMeta, channel_id: Snowflake, @@ -78,18 +76,17 @@ impl Message { } impl UserMeta { + /// Sends a message to the Spacebar server. + /// # Arguments + /// * `url_api` - The URL of the Spacebar server's API. + /// * `message` - The [`Message`] that will be sent to the Spacebar server. + /// * `limits_user` - The [`Limits`] of the user. + /// * `limits_instance` - The [`Limits`] of the instance. + /// * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. + /// # Errors + /// * [`ChorusLibError`] - If the message cannot be sent. + /// # Notes /// Shorthand call for Message::send() - /** - Sends a message to the Spacebar server. - # Arguments - * `url_api` - The URL of the Spacebar server's API. - * `message` - The [`Message`] that will be sent to the Spacebar server. - * `limits_user` - The [`Limits`] of the user. - * `limits_instance` - The [`Limits`] of the instance. - * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. - # Errors - * [`ChorusLibError`] - If the message cannot be sent. - */ pub async fn send_message( &mut self, message: &mut MessageSendSchema, diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index 35dbb94..70c16ce 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -8,9 +8,7 @@ use crate::{ types::{self, PublicUser, Snowflake}, }; -/** -Useful metadata for working with [`types::Reaction`], bundled together nicely. - */ +/// Useful metadata for working with [`types::Reaction`], bundled together nicely. pub struct ReactionMeta { pub message_id: types::Snowflake, pub channel_id: types::Snowflake, diff --git a/src/api/users/users.rs b/src/api/users/users.rs index bd46a36..7c67c7d 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -140,16 +140,14 @@ impl User { } impl Instance { - /** - Get a user object by id, or get the current user. - # Arguments - * `token` - A valid access token for the API. - * `id` - The id of the user that will be retrieved. If this is None, the current user will be retrieved. - # Errors - * [`ChorusLibError`] - If the request fails. - # Notes - This function is a wrapper around [`User::get`]. - */ + // Get a user object by id, or get the current user. + // # Arguments + // * `token` - A valid access token for the API. + // * `id` - The id of the user that will be retrieved. If this is None, the current user will be retrieved. + // # Errors + // * [`ChorusLibError`] - If the request fails. + // # Notes + // This function is a wrapper around [`User::get`]. pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult { let mut user = UserMeta::shell(Rc::new(RefCell::new(self.clone())), token); let result = User::get(&mut user, id).await; diff --git a/src/instance.rs b/src/instance.rs index 15c513c..d40d900 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -14,10 +14,8 @@ use crate::types::{GeneralConfiguration, User, UserSettings}; use crate::UrlBundle; #[derive(Debug, Clone)] -/** -The [`Instance`] what you will be using to perform all sorts of actions on the Spacebar server. -If `limits_information` is `None`, then the instance will not be rate limited. - */ +/// The [`Instance`]; what you will be using to perform all sorts of actions on the Spacebar server. +/// If `limits_information` is `None`, then the instance will not be rate limited. pub struct Instance { pub urls: UrlBundle, pub instance_info: GeneralConfiguration, diff --git a/src/types/entities/attachment.rs b/src/types/entities/attachment.rs index 7bd9d2b..4261203 100644 --- a/src/types/entities/attachment.rs +++ b/src/types/entities/attachment.rs @@ -41,11 +41,7 @@ pub struct PartialDiscordFileAttachment { } impl PartialDiscordFileAttachment { - /** - Moves `self.content` out of `self` and returns it. - # Returns - Vec - */ + /// Moves `self.content` out of `self` and returns it. pub fn move_content(self) -> (Vec, PartialDiscordFileAttachment) { let content = self.content; let updated_struct = PartialDiscordFileAttachment { From 322894e4e9fa1b07905718dbca0ff789fafef799 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 10 Jul 2023 17:22:31 +0200 Subject: [PATCH 002/237] UrlBundle slightly better docs --- src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 77425b8..5b14544 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,9 +18,18 @@ pub mod voice; #[derive(Clone, Default, Debug, PartialEq, Eq)] /// A URLBundle is a struct which bundles together the API-, Gateway- and CDN-URLs of a Spacebar /// instance. +/// # Notes +/// All the urls can be found on the /api/policies/instance/domains endpoint of a spacebar server pub struct UrlBundle { + /// The api's url. + /// Ex: `https://old.server.spacebar.chat/api` pub api: String, + /// The gateway websocket url. + /// Note that because this is a websocket url, it will always start with `wss://` + /// Ex: `wss://gateway.old.server.spacebar.chat` pub wss: String, + /// The CDN's url. + /// Ex: `https://cdn.old.server.spacebar.chat` pub cdn: String, } From 18ac7b5708aaf3e9c7348af453c0ec50a03434ee Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 10 Jul 2023 18:06:45 +0200 Subject: [PATCH 003/237] Rustdoc warnings + misc changes --- src/api/auth/register.rs | 2 +- src/api/channels/messages.rs | 15 +++------ src/api/channels/reactions.rs | 20 ++++++------ src/api/guilds/member.rs | 12 +++---- src/api/guilds/roles.rs | 32 ++++--------------- src/api/policies/instance/instance.rs | 2 +- src/api/policies/instance/ratelimits.rs | 2 -- src/api/users/relationships.rs | 12 ++++--- src/api/users/users.rs | 9 +++--- src/gateway.rs | 4 +-- src/instance.rs | 7 +---- src/types/entities/application.rs | 6 ++-- src/types/entities/audit_log.rs | 4 +-- src/types/entities/auto_moderation.rs | 28 ++++++++--------- src/types/entities/guild.rs | 16 +++++----- src/types/entities/integration.rs | 4 +-- src/types/entities/relationship.rs | 4 +-- src/types/entities/role.rs | 4 +-- src/types/entities/stage_instance.rs | 6 ++-- src/types/entities/template.rs | 2 +- src/types/entities/voice_state.rs | 2 +- src/types/entities/webhook.rs | 2 +- src/types/events/application.rs | 2 +- src/types/events/auto_moderation.rs | 8 ++--- src/types/events/call.rs | 2 +- src/types/events/channel.rs | 10 +++--- src/types/events/guild.rs | 42 ++++++++++++------------- src/types/events/integration.rs | 6 ++-- src/types/events/interaction.rs | 2 +- src/types/events/invite.rs | 4 +-- src/types/events/lazy_request.rs | 2 +- src/types/events/message.rs | 6 ++-- src/types/events/mod.rs | 5 +-- src/types/events/presence.rs | 4 +-- src/types/events/ready.rs | 4 +-- src/types/events/relationship.rs | 4 +-- src/types/events/request_members.rs | 2 +- src/types/events/stage_instance.rs | 6 ++-- src/types/events/thread.rs | 12 +++---- src/types/events/user.rs | 2 +- src/types/events/voice.rs | 4 +-- src/types/events/webhooks.rs | 2 +- src/types/interfaces/status.rs | 2 +- src/types/utils/snowflake.rs | 2 +- 44 files changed, 147 insertions(+), 181 deletions(-) diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index a6849cc..e7b9d48 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -20,7 +20,7 @@ impl Instance { /// /// # Errors /// - /// * [`ChorusLibError`] - If the server does not respond. + /// * [`crate::errors::ChorusError`] - If the server does not respond. pub async fn register_account( &mut self, register_schema: &RegisterSchema, diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index c46409f..73afda9 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -4,6 +4,7 @@ use reqwest::{multipart, Client}; use serde_json::to_string; use crate::api::LimitType; +use crate::errors::ChorusResult; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; use crate::types::{Message, MessageSendSchema, PartialDiscordFileAttachment, Snowflake}; @@ -13,17 +14,14 @@ impl Message { /// # Arguments /// * `url_api` - The URL of the Spacebar server's API. /// * `message` - The [`Message`] that will be sent to the Spacebar server. - /// * `limits_user` - The [`Limits`] of the user. - /// * `limits_instance` - The [`Limits`] of the instance. - /// * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. /// # Errors - /// * [`ChorusLibError`] - If the message cannot be sent. + /// * [`crate::errors::ChorusError`] - If the message cannot be sent. pub async fn send( user: &mut UserMeta, channel_id: Snowflake, message: &mut MessageSendSchema, files: Option>, - ) -> Result { + ) -> ChorusResult { let url_api = user.belongs_to.borrow().urls.api.clone(); if files.is_none() { @@ -80,11 +78,8 @@ impl UserMeta { /// # Arguments /// * `url_api` - The URL of the Spacebar server's API. /// * `message` - The [`Message`] that will be sent to the Spacebar server. - /// * `limits_user` - The [`Limits`] of the user. - /// * `limits_instance` - The [`Limits`] of the instance. - /// * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. /// # Errors - /// * [`ChorusLibError`] - If the message cannot be sent. + /// * [`crate::errors::ChorusError`] - If the message cannot be sent. /// # Notes /// Shorthand call for Message::send() pub async fn send_message( @@ -92,7 +87,7 @@ impl UserMeta { message: &mut MessageSendSchema, channel_id: Snowflake, files: Option>, - ) -> Result { + ) -> ChorusResult { Message::send(self, channel_id, message, files).await } } diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index 70c16ce..fe1e57f 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -20,10 +20,10 @@ impl ReactionMeta { /// # Arguments /// * `user` - A mutable reference to a [`UserMeta`] instance. /// # Returns - /// A `Result` [`()`] [`crate::errors::ChorusLibError`] if something went wrong. + /// A `Result` [`()`] [`crate::errors::ChorusError`] if something went wrong. /// Fires a `Message Reaction Remove All` Gateway event. /// # Reference - /// See [https://discord.com/developers/docs/resources/channel#delete-all-reactions](https://discord.com/developers/docs/resources/channel#delete-all-reactions) + /// See pub async fn delete_all(&self, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/", @@ -47,7 +47,7 @@ impl ReactionMeta { /// # Returns /// A Result that is [`Err(crate::errors::ChorusLibError)`] if something went wrong. /// # Reference - /// See [https://discord.com/developers/docs/resources/channel#get-reactions](https://discord.com/developers/docs/resources/channel#get-reactions) + /// See pub async fn get(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/", @@ -76,7 +76,7 @@ impl ReactionMeta { /// A Result that is [`Err(crate::errors::ChorusLibError)`] if something went wrong. /// Fires a `Message Reaction Remove Emoji` Gateway event. /// # Reference - /// See [https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji](https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji) + /// See pub async fn delete_emoji(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/", @@ -103,9 +103,9 @@ impl ReactionMeta { /// format name:id with the emoji name and emoji id. /// * `user` - A mutable reference to a [`UserMeta`] instance. /// # Returns - /// A `Result` containing [`()`] or a [`crate::errors::ChorusLibError`]. + /// A `Result` containing [`()`] or a [`crate::errors::ChorusError`]. /// # Reference - /// See [https://discord.com/developers/docs/resources/channel#create-reaction](https://discord.com/developers/docs/resources/channel#create-reaction) + /// See /// pub async fn create(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( @@ -129,10 +129,10 @@ impl ReactionMeta { /// format name:id with the emoji name and emoji id. /// * `user` - A mutable reference to a [`UserMeta`] instance. /// # Returns - /// A `Result` containing [`()`] or a [`crate::errors::ChorusLibError`]. + /// A `Result` containing [`()`] or a [`crate::errors::ChorusError`]. /// Fires a `Message Reaction Remove` Gateway event. /// # Reference - /// See [https://discord.com/developers/docs/resources/channel#delete-own-reaction](https://discord.com/developers/docs/resources/channel#delete-own-reaction) + /// See pub async fn remove(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me/", @@ -157,10 +157,10 @@ impl ReactionMeta { /// format name:id with the emoji name and emoji id. /// * `user` - A mutable reference to a [`UserMeta`] instance. /// # Returns - /// A `Result` containing [`()`] or a [`crate::errors::ChorusLibError`]. + /// A [`ChorusResult`] containing [`()`] or a [`crate::errors::ChorusError`]. /// Fires a Message Reaction Remove Gateway event. /// # Reference - /// See [https://discord.com/developers/docs/resources/channel#delete-own-reaction](https://discord.com/developers/docs/resources/channel#delete-own-reaction) + /// See pub async fn delete_user( &self, user_id: Snowflake, diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index 5fa99cd..c7e26b9 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -5,7 +5,7 @@ use crate::{ errors::ChorusResult, instance::UserMeta, ratelimiter::ChorusRequest, - types::{self, Snowflake}, + types::{self, GuildMember, Snowflake}, }; impl types::GuildMember { @@ -19,12 +19,12 @@ impl types::GuildMember { /// /// # Returns /// - /// A [`Result`] containing a [`GuildMember`] if the request succeeds, or a [`ChorusLibError`] if the request fails. + /// A [`ChorusResult`] containing a [`GuildMember`] if the request succeeds. pub async fn get( user: &mut UserMeta, guild_id: Snowflake, member_id: Snowflake, - ) -> ChorusResult { + ) -> ChorusResult { let url = format!( "{}/guilds/{}/members/{}/", user.belongs_to.borrow().urls.api, @@ -36,7 +36,7 @@ impl types::GuildMember { limit_type: LimitType::Guild(guild_id), }; chorus_request - .deserialize_response::(user) + .deserialize_response::(user) .await } @@ -51,7 +51,7 @@ impl types::GuildMember { /// /// # Returns /// - /// An `Result` containing a `ChorusLibError` if the request fails, or `()` if the request succeeds. + /// A [`ChorusResult`] containing a [`crate::errors::ChorusError`] if the request fails, or `()` if the request succeeds. pub async fn add_role( user: &mut UserMeta, guild_id: Snowflake, @@ -83,7 +83,7 @@ impl types::GuildMember { /// /// # Returns /// - /// A `Result` containing a `ChorusLibError` if the request fails, or `()` if the request succeeds. + /// A [`ChorusResult`] containing a [`crate::errors::ChorusError`] if the request fails, or `()` if the request succeeds. pub async fn remove_role( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 1d1bc68..f8cade9 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -6,7 +6,7 @@ use crate::{ errors::{ChorusError, ChorusResult}, instance::UserMeta, ratelimiter::ChorusRequest, - types::{self, RoleCreateModifySchema, RoleObject, Snowflake}, + types::{self, RoleCreateModifySchema, RoleObject, RolePositionUpdateSchema, Snowflake}, }; impl types::RoleObject { @@ -20,10 +20,6 @@ impl types::RoleObject { /// # Returns /// /// An `Option` containing a `Vec` of [`RoleObject`]s if roles were found, or `None` if no roles were found. - /// - /// # Errors - /// - /// Returns a [`ChorusLibError`] if the request fails or if the response is invalid. pub async fn get_all( user: &mut UserMeta, guild_id: Snowflake, @@ -57,11 +53,7 @@ impl types::RoleObject { /// /// # Returns /// - /// A `Result` containing the retrieved [`RoleObject`] if successful, or a [`ChorusLibError`] if the request fails or if the response is invalid. - /// - /// # Errors - /// - /// Returns a [`ChorusLibError`] if the request fails or if the response is invalid. + /// A `Result` containing the retrieved [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. pub async fn get( user: &mut UserMeta, guild_id: Snowflake, @@ -92,11 +84,7 @@ impl types::RoleObject { /// /// # Returns /// - /// A `Result` containing the newly created [`RoleObject`] if successful, or a [`ChorusLibError`] if the request fails or if the response is invalid. - /// - /// # Errors - /// - /// Returns a [`ChorusLibError`] if the request fails or if the response is invalid. + /// A `Result` containing the newly created [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. pub async fn create( user: &mut UserMeta, guild_id: Snowflake, @@ -131,15 +119,11 @@ impl types::RoleObject { /// /// # Returns /// - /// A `Result` containing the updated [`RoleObject`] if successful, or a [`ChorusLibError`] if the request fails or if the response is invalid. - /// - /// # Errors - /// - /// Returns a [`ChorusLibError`] if the request fails or if the response is invalid. + /// A `Result` containing the updated [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. pub async fn position_update( user: &mut UserMeta, guild_id: Snowflake, - role_position_update_schema: types::RolePositionUpdateSchema, + role_position_update_schema: RolePositionUpdateSchema, ) -> ChorusResult { let url = format!( "{}/guilds/{}/roles/", @@ -173,11 +157,7 @@ impl types::RoleObject { /// /// # Returns /// - /// A `Result` containing the updated [`RoleObject`] if successful, or a [`ChorusLibError`] if the request fails or if the response is invalid. - /// - /// # Errors - /// - /// Returns a [`ChorusLibError`] if the request fails or if the response is invalid. + /// A `Result` containing the updated [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. pub async fn update( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/policies/instance/instance.rs b/src/api/policies/instance/instance.rs index 75f832c..d015778 100644 --- a/src/api/policies/instance/instance.rs +++ b/src/api/policies/instance/instance.rs @@ -7,7 +7,7 @@ use crate::types::GeneralConfiguration; impl Instance { /// Gets the instance policies schema. /// # Errors - /// [`ChorusLibError`] - If the request fails. + /// [`ChorusError`] - If the request fails. pub async fn general_configuration_schema(&self) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/policies/instance/"; let request = match self.client.get(&endpoint_url).send().await { diff --git a/src/api/policies/instance/ratelimits.rs b/src/api/policies/instance/ratelimits.rs index 125af32..5e7def7 100644 --- a/src/api/policies/instance/ratelimits.rs +++ b/src/api/policies/instance/ratelimits.rs @@ -22,8 +22,6 @@ pub enum LimitType { } /// A struct that represents the current ratelimits, either instance-wide or user-wide. -/// Unlike [`RateLimits`], this struct shows the current ratelimits, not the rate limit -/// configuration for the instance. /// See for more information. #[derive(Debug, Clone)] pub struct Limit { diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index 39c75d8..a864706 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -6,7 +6,9 @@ use crate::{ errors::ChorusResult, instance::UserMeta, ratelimiter::ChorusRequest, - types::{self, CreateUserRelationshipSchema, RelationshipType, Snowflake}, + types::{ + self, CreateUserRelationshipSchema, FriendRequestSendSchema, RelationshipType, Snowflake, + }, }; impl UserMeta { @@ -61,10 +63,10 @@ impl UserMeta { /// * `schema` - A [`FriendRequestSendSchema`] struct that holds the information about the friend request to be sent. /// /// # Returns - /// This function returns a [`Result`] that holds a [`ChorusLibError`] if the request fails. + /// This function returns a [`ChorusResult`]. pub async fn send_friend_request( &mut self, - schema: types::FriendRequestSendSchema, + schema: FriendRequestSendSchema, ) -> ChorusResult<()> { let url = format!( "{}/users/@me/relationships/", @@ -91,7 +93,7 @@ impl UserMeta { /// * [`RelationshipType::Blocked`]: Blocks the specified user_id. /// /// # Returns - /// This function returns an [`Result`] that holds a [`ChorusLibError`] if the request fails. + /// This function returns an [`ChorusResult`]. pub async fn modify_user_relationship( &mut self, user_id: Snowflake, @@ -149,7 +151,7 @@ impl UserMeta { /// * `user_id` - ID of the user to remove the relationship with. /// /// # Returns - /// This function returns a [`Result`] that holds a [`ChorusLibError`] if the request fails. + /// This function returns a [`ChorusResult`]. pub async fn remove_relationship(&mut self, user_id: Snowflake) -> ChorusResult<()> { let url = format!( "{}/users/@me/relationships/{}/", diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 7c67c7d..0f6a5ee 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -19,11 +19,10 @@ impl UserMeta { /// * `token` - A valid access token for the API. /// * `url_api` - The URL to the API. /// * `id` - The id of the user that will be retrieved. If this is None, the current user will be retrieved. - /// * `instance_limits` - The [`Limits`] of the instance. /// /// # Errors /// - /// * [`ChorusLibError`] - If the request fails. + /// * [`ChorusError`] - If the request fails. pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { User::get(user, id).await } @@ -44,7 +43,7 @@ impl UserMeta { /// /// # Errors /// - /// Returns an `ChorusLibError` if the request fails or if a password is required but not provided. + /// Returns an [`ChorusError`] if the request fails or if a password is required but not provided. pub async fn modify(&mut self, modify_schema: UserModifySchema) -> ChorusResult { if modify_schema.new_password.is_some() || modify_schema.email.is_some() @@ -76,7 +75,7 @@ impl UserMeta { /// /// # Returns /// - /// Returns `()` if the user was successfully deleted, or a `ChorusLibError` if an error occurred. + /// Returns `()` if the user was successfully deleted, or a [`ChorusError`] if an error occurred. pub async fn delete(mut self) -> ChorusResult<()> { let request = Client::new() .post(format!( @@ -145,7 +144,7 @@ impl Instance { // * `token` - A valid access token for the API. // * `id` - The id of the user that will be retrieved. If this is None, the current user will be retrieved. // # Errors - // * [`ChorusLibError`] - If the request fails. + // * [`ChorusError`] - If the request fails. // # Notes // This function is a wrapper around [`User::get`]. pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult { diff --git a/src/gateway.rs b/src/gateway.rs index ed96aac..3e6a604 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -72,7 +72,7 @@ const GATEWAY_LAZY_REQUEST: u8 = 14; /// The amount of time we wait for a heartbeat ack before resending our heartbeat in ms const HEARTBEAT_ACK_TIMEOUT: u128 = 2000; -/// Represents a messsage received from the gateway. This will be either a [GatewayReceivePayload], containing events, or a [GatewayError]. +/// Represents a messsage received from the gateway. This will be either a [types::GatewayReceivePayload], containing events, or a [GatewayError]. /// This struct is used internally when handling messages. #[derive(Clone, Debug)] pub struct GatewayMessage { @@ -144,7 +144,7 @@ impl GatewayMessage { /// Represents a handle to a Gateway connection. A Gateway connection will create observable /// [`GatewayEvents`](GatewayEvent), which you can subscribe to. Gateway events include all currently -/// implemented [Types] with the trait [`WebSocketEvent`] +/// implemented types with the trait [`WebSocketEvent`] /// Using this handle you can also send Gateway Events directly. #[derive(Debug)] pub struct GatewayHandle { diff --git a/src/instance.rs b/src/instance.rs index d40d900..f7d2c2a 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -30,12 +30,7 @@ pub struct LimitsInformation { } impl Instance { - /// Creates a new [`Instance`]. - /// # Arguments - /// * `urls` - The [`URLBundle`] that contains all the URLs that are needed to connect to the Spacebar server. - /// * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. - /// # Errors - /// * [`InstanceError`] - If the instance cannot be created. + /// Creates a new [`Instance`] from the [relevant instance urls](UrlBundle), where `limited` is whether or not to automatically use rate limits. pub async fn new(urls: UrlBundle, limited: bool) -> ChorusResult { let limits_information; if limited { diff --git a/src/types/entities/application.rs b/src/types/entities/application.rs index 6cac20b..15e259c 100644 --- a/src/types/entities/application.rs +++ b/src/types/entities/application.rs @@ -168,7 +168,7 @@ pub struct ApplicationCommandInteractionDataOption { } #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] -/// See https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-guild-application-command-permissions-structure +/// See pub struct GuildApplicationCommandPermissions { pub id: Snowflake, pub application_id: Snowflake, @@ -177,7 +177,7 @@ pub struct GuildApplicationCommandPermissions { } #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] -/// See https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-structure +/// See pub struct ApplicationCommandPermission { pub id: Snowflake, #[serde(rename = "type")] @@ -189,7 +189,7 @@ pub struct ApplicationCommandPermission { #[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, PartialEq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[repr(u8)] -/// See https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permission-type +/// See pub enum ApplicationCommandPermissionType { #[default] Role = 1, diff --git a/src/types/entities/audit_log.rs b/src/types/entities/audit_log.rs index 1e04e8b..8965a05 100644 --- a/src/types/entities/audit_log.rs +++ b/src/types/entities/audit_log.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; #[derive(Serialize, Deserialize, Debug, Default, Clone)] -/// See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object +/// See pub struct AuditLogEntry { pub target_id: Option, pub changes: Option>, @@ -17,7 +17,7 @@ pub struct AuditLogEntry { } #[derive(Serialize, Deserialize, Debug, Default, Clone)] -/// See https://discord.com/developers/docs/resources/audit-log#audit-log-change-object +/// See pub struct AuditLogChange { pub new_value: Option, pub old_value: Option, diff --git a/src/types/entities/auto_moderation.rs b/src/types/entities/auto_moderation.rs index 144aa4b..0feadde 100644 --- a/src/types/entities/auto_moderation.rs +++ b/src/types/entities/auto_moderation.rs @@ -4,7 +4,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; use crate::types::utils::Snowflake; #[derive(Serialize, Deserialize, Debug, Default, Clone)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object +/// See pub struct AutoModerationRule { pub id: Snowflake, pub guild_id: Snowflake, @@ -22,7 +22,7 @@ pub struct AutoModerationRule { #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-event-types +/// See pub enum AutoModerationRuleEventType { #[default] MessageSend = 1, @@ -31,7 +31,7 @@ pub enum AutoModerationRuleEventType { #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-types +/// See pub enum AutoModerationRuleTriggerType { #[default] Keyword = 1, @@ -42,7 +42,7 @@ pub enum AutoModerationRuleTriggerType { #[derive(Serialize, Deserialize, Debug, Clone, Default)] #[serde(untagged)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata +/// See pub enum AutoModerationRuleTriggerMetadata { ForKeyword(AutoModerationRuleTriggerMetadataForKeyword), ForKeywordPreset(AutoModerationRuleTriggerMetadataForKeywordPreset), @@ -52,7 +52,7 @@ pub enum AutoModerationRuleTriggerMetadata { } #[derive(Serialize, Deserialize, Debug, Clone, Default)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata +/// See pub struct AutoModerationRuleTriggerMetadataForKeyword { pub keyword_filter: Vec, pub regex_patterns: Vec, @@ -60,14 +60,14 @@ pub struct AutoModerationRuleTriggerMetadataForKeyword { } #[derive(Serialize, Deserialize, Debug, Clone, Default)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata +/// See pub struct AutoModerationRuleTriggerMetadataForKeywordPreset { pub presets: Vec, pub allow_list: Vec, } #[derive(Serialize, Deserialize, Debug, Clone, Default)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata +/// See pub struct AutoModerationRuleTriggerMetadataForMentionSpam { /// Max 50 pub mention_total_limit: u8, @@ -77,7 +77,7 @@ pub struct AutoModerationRuleTriggerMetadataForMentionSpam { #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-keyword-preset-types +/// See pub enum AutoModerationRuleKeywordPresetType { #[default] Profanity = 1, @@ -86,7 +86,7 @@ pub enum AutoModerationRuleKeywordPresetType { } #[derive(Serialize, Deserialize, Debug, Clone, Default)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object +/// See pub struct AutoModerationAction { #[serde(rename = "type")] pub action_type: AutoModerationActionType, @@ -96,7 +96,7 @@ pub struct AutoModerationAction { #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-types +/// See pub enum AutoModerationActionType { #[default] BlockMessage = 1, @@ -106,7 +106,7 @@ pub enum AutoModerationActionType { #[derive(Serialize, Deserialize, Debug, Clone, Default)] #[serde(untagged)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata +/// See pub enum AutoModerationActionMetadata { ForBlockMessage(AutoModerationActionMetadataForBlockMessage), ForSendAlertMessage(AutoModerationActionMetadataForSendAlertMessage), @@ -116,19 +116,19 @@ pub enum AutoModerationActionMetadata { } #[derive(Serialize, Deserialize, Debug, Clone, Default)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata +/// See pub struct AutoModerationActionMetadataForBlockMessage { pub custom_message: Option, } #[derive(Serialize, Deserialize, Debug, Clone, Default)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata +/// See pub struct AutoModerationActionMetadataForSendAlertMessage { pub channel_id: Snowflake, } #[derive(Serialize, Deserialize, Debug, Clone, Default)] -/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata +/// See pub struct AutoModerationActionMetadataForTimeout { /// Max 2419200 pub duration_seconds: u32, diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 857ed2a..5c8eaf0 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -9,7 +9,7 @@ use crate::types::{ utils::Snowflake, }; -/// See https://discord.com/developers/docs/resources/guild +/// See #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Guild { @@ -90,7 +90,7 @@ pub struct Guild { pub widget_enabled: Option, } -/// See https://docs.spacebar.chat/routes/#get-/guilds/-guild_id-/bans/-user- +/// See #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildBan { @@ -99,7 +99,7 @@ pub struct GuildBan { pub reason: Option, } -/// See https://docs.spacebar.chat/routes/#cmp--schemas-invite +/// See #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildInvite { @@ -134,7 +134,7 @@ pub struct GuildCreateResponse { } #[derive(Serialize, Deserialize, Debug, Default, Clone)] -/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object +/// See pub struct GuildScheduledEvent { pub id: Snowflake, pub guild_id: Snowflake, @@ -156,7 +156,7 @@ pub struct GuildScheduledEvent { #[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)] #[repr(u8)] -/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-privacy-level +/// See pub enum GuildScheduledEventPrivacyLevel { #[default] GuildOnly = 2, @@ -164,7 +164,7 @@ pub enum GuildScheduledEventPrivacyLevel { #[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)] #[repr(u8)] -/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-status +/// See pub enum GuildScheduledEventStatus { #[default] Scheduled = 1, @@ -175,7 +175,7 @@ pub enum GuildScheduledEventStatus { #[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)] #[repr(u8)] -/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-entity-types +/// See pub enum GuildScheduledEventEntityType { #[default] StageInstance = 1, @@ -184,7 +184,7 @@ pub enum GuildScheduledEventEntityType { } #[derive(Serialize, Deserialize, Debug, Default, Clone)] -/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-entity-metadata +/// See pub struct GuildScheduledEventEntityMetadata { pub location: Option, } diff --git a/src/types/entities/integration.rs b/src/types/entities/integration.rs index 8076e70..f083dae 100644 --- a/src/types/entities/integration.rs +++ b/src/types/entities/integration.rs @@ -8,7 +8,7 @@ use crate::types::{ #[derive(Default, Debug, Deserialize, Serialize, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] -/// See https://discord.com/developers/docs/resources/guild#integration-object-integration-structure +/// See pub struct Integration { pub id: Snowflake, pub name: String, @@ -33,7 +33,7 @@ pub struct Integration { } #[derive(Default, Debug, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/resources/guild#integration-account-object-integration-account-structure +/// See pub struct IntegrationAccount { pub id: String, pub name: String, diff --git a/src/types/entities/relationship.rs b/src/types/entities/relationship.rs index a6abc09..168f362 100644 --- a/src/types/entities/relationship.rs +++ b/src/types/entities/relationship.rs @@ -7,7 +7,7 @@ use crate::types::Snowflake; use super::PublicUser; #[derive(Debug, Deserialize, Serialize, Clone, Default, PartialEq, Eq)] -/// See https://discord-userdoccers.vercel.app/resources/user#relationship-structure +/// See pub struct Relationship { pub id: Snowflake, #[serde(rename = "type")] @@ -19,7 +19,7 @@ pub struct Relationship { #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default, Eq, PartialEq)] #[repr(u8)] -/// See https://discord-userdoccers.vercel.app/resources/user#relationship-type +/// See pub enum RelationshipType { Suggestion = 6, Implicit = 5, diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 1719d28..ef93b5d 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -6,7 +6,7 @@ use crate::types::utils::Snowflake; #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] -/// See https://discord.com/developers/docs/topics/permissions#role-object +/// See pub struct RoleObject { pub id: Snowflake, pub name: String, @@ -35,7 +35,7 @@ pub struct RoleSubscriptionData { } #[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq)] -/// See https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure +/// See pub struct RoleTags { #[serde(default)] #[serde(deserialize_with = "deserialize_option_number_from_string")] diff --git a/src/types/entities/stage_instance.rs b/src/types/entities/stage_instance.rs index b2d19c3..8810f52 100644 --- a/src/types/entities/stage_instance.rs +++ b/src/types/entities/stage_instance.rs @@ -4,12 +4,12 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; use crate::types::Snowflake; #[derive(Serialize, Deserialize, Debug, Default, Clone)] -/// See https://discord.com/developers/docs/resources/stage-instance +/// See pub struct StageInstance { pub id: Snowflake, pub guild_id: Snowflake, pub channel_id: Snowflake, - /// 1 - 120 chars + /// 1 - 120 characters pub topic: String, pub privacy_level: StageInstancePrivacyLevel, /// deprecated, apparently @@ -20,7 +20,7 @@ pub struct StageInstance { #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -/// See https://discord.com/developers/docs/resources/stage-instance#stage-instance-object-privacy-level +/// See pub enum StageInstancePrivacyLevel { /// deprecated, apparently Public = 1, diff --git a/src/types/entities/template.rs b/src/types/entities/template.rs index b6eb3e9..2f934c9 100644 --- a/src/types/entities/template.rs +++ b/src/types/entities/template.rs @@ -6,7 +6,7 @@ use crate::types::{ utils::Snowflake, }; -/// See https://docs.spacebar.chat/routes/#cmp--schemas-template +/// See #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildTemplate { diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index aafc07f..94d3d79 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -6,7 +6,7 @@ use crate::types::{ utils::Snowflake, }; -/// See https://docs.spacebar.chat/routes/#cmp--schemas-voicestate +/// See #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct VoiceState { diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index 521b93f..f953149 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -5,7 +5,7 @@ use crate::types::{ utils::Snowflake, }; -/// See https://docs.spacebar.chat/routes/#cmp--schemas-webhook +/// See #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Webhook { diff --git a/src/types/events/application.rs b/src/types/events/application.rs index 8afb374..7fee577 100644 --- a/src/types/events/application.rs +++ b/src/types/events/application.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{GuildApplicationCommandPermissions, WebSocketEvent}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#application-command-permissions-update +/// See pub struct ApplicationCommandPermissionsUpdate { #[serde(flatten)] pub permissions: GuildApplicationCommandPermissions, diff --git a/src/types/events/auto_moderation.rs b/src/types/events/auto_moderation.rs index d82aa02..0a1600b 100644 --- a/src/types/events/auto_moderation.rs +++ b/src/types/events/auto_moderation.rs @@ -6,7 +6,7 @@ use crate::types::{ }; #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-create +/// See pub struct AutoModerationRuleCreate { #[serde(flatten)] pub rule: AutoModerationRule, @@ -15,7 +15,7 @@ pub struct AutoModerationRuleCreate { impl WebSocketEvent for AutoModerationRuleCreate {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-update +/// See pub struct AutoModerationRuleUpdate { #[serde(flatten)] pub rule: AutoModerationRule, @@ -24,7 +24,7 @@ pub struct AutoModerationRuleUpdate { impl WebSocketEvent for AutoModerationRuleUpdate {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-delete +/// See pub struct AutoModerationRuleDelete { #[serde(flatten)] pub rule: AutoModerationRule, @@ -33,7 +33,7 @@ pub struct AutoModerationRuleDelete { impl WebSocketEvent for AutoModerationRuleDelete {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-action-execution +/// See pub struct AutoModerationActionExecution { pub guild_id: Snowflake, pub action: AutoModerationAction, diff --git a/src/types/events/call.rs b/src/types/events/call.rs index 67225fb..e37c19d 100644 --- a/src/types/events/call.rs +++ b/src/types/events/call.rs @@ -50,7 +50,7 @@ impl WebSocketEvent for CallDelete {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// Officially Undocumented; -/// See https://unofficial-discord-docs.vercel.app/gateway/op13; +/// See ; /// /// Ex: {"op":13,"d":{"channel_id":"837609115475771392"}} pub struct CallSync { diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 99c7640..488bc47 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -4,7 +4,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Deserialize, Serialize)] -/// See https://discord.com/developers/docs/topics/gateway-events#channel-pins-update +/// See pub struct ChannelPinsUpdate { pub guild_id: Option, pub channel_id: Snowflake, @@ -14,7 +14,7 @@ pub struct ChannelPinsUpdate { impl WebSocketEvent for ChannelPinsUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#channel-create +/// See pub struct ChannelCreate { #[serde(flatten)] pub channel: Channel, @@ -23,7 +23,7 @@ pub struct ChannelCreate { impl WebSocketEvent for ChannelCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#channel-update +/// See pub struct ChannelUpdate { #[serde(flatten)] pub channel: Channel, @@ -42,7 +42,7 @@ pub struct ChannelUnreadUpdate { #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// Contains very few fields from [Channel] -/// See also [ChannelUnreadUpdates] +/// See also [ChannelUnreadUpdate] pub struct ChannelUnreadUpdateObject { pub id: Snowflake, pub last_message_id: Snowflake, @@ -52,7 +52,7 @@ pub struct ChannelUnreadUpdateObject { impl WebSocketEvent for ChannelUnreadUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#channel-delete +/// See pub struct ChannelDelete { #[serde(flatten)] pub channel: Channel, diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index ae69681..2cbdbd0 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -10,7 +10,7 @@ use crate::types::{ use super::PresenceUpdate; #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-create; +/// See ; /// Received to give data about a guild; // This one is particularly painful, it can be a Guild object with an extra field or an unavailable guild object pub struct GuildCreate { @@ -34,7 +34,7 @@ impl Default for GuildCreateDataOption { impl WebSocketEvent for GuildCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-ban-add-guild-ban-add-event-fields; +/// See ; /// Received to give info about a user being banned from a guild; pub struct GuildBanAdd { pub guild_id: Snowflake, @@ -44,7 +44,7 @@ pub struct GuildBanAdd { impl WebSocketEvent for GuildBanAdd {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-ban-remove; +/// See ; /// Received to give info about a user being unbanned from a guild; pub struct GuildBanRemove { pub guild_id: Snowflake, @@ -54,7 +54,7 @@ pub struct GuildBanRemove { impl WebSocketEvent for GuildBanRemove {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-update; +/// See ; /// Received to give info about a guild being updated; pub struct GuildUpdate { #[serde(flatten)] @@ -64,7 +64,7 @@ pub struct GuildUpdate { impl WebSocketEvent for GuildUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-delete; +/// See ; /// Received to tell the client about a guild being deleted; pub struct GuildDelete { #[serde(flatten)] @@ -74,7 +74,7 @@ pub struct GuildDelete { impl WebSocketEvent for GuildDelete {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-audit-log-entry-create; +/// See ; /// Received to the client about an audit log entry being added; pub struct GuildAuditLogEntryCreate { #[serde(flatten)] @@ -84,7 +84,7 @@ pub struct GuildAuditLogEntryCreate { impl WebSocketEvent for GuildAuditLogEntryCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-emojis-update; +/// See ; /// Received to tell the client about a change to a guild's emoji list; pub struct GuildEmojisUpdate { pub guild_id: Snowflake, @@ -94,7 +94,7 @@ pub struct GuildEmojisUpdate { impl WebSocketEvent for GuildEmojisUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-stickers-update; +/// See ; /// Received to tell the client about a change to a guild's sticker list; pub struct GuildStickersUpdate { pub guild_id: Snowflake, @@ -104,7 +104,7 @@ pub struct GuildStickersUpdate { impl WebSocketEvent for GuildStickersUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-integrations-update +/// See pub struct GuildIntegrationsUpdate { pub guild_id: Snowflake, } @@ -112,7 +112,7 @@ pub struct GuildIntegrationsUpdate { impl WebSocketEvent for GuildIntegrationsUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-member-add; +/// See ; /// Received to tell the client about a user joining a guild; pub struct GuildMemberAdd { #[serde(flatten)] @@ -123,7 +123,7 @@ pub struct GuildMemberAdd { impl WebSocketEvent for GuildMemberAdd {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-member-remove; +/// See ; /// Received to tell the client about a user leaving a guild; pub struct GuildMemberRemove { pub guild_id: Snowflake, @@ -133,7 +133,7 @@ pub struct GuildMemberRemove { impl WebSocketEvent for GuildMemberRemove {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-member-update +/// See pub struct GuildMemberUpdate { pub guild_id: Snowflake, pub roles: Vec, @@ -151,7 +151,7 @@ pub struct GuildMemberUpdate { impl WebSocketEvent for GuildMemberUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-members-chunk +/// See pub struct GuildMembersChunk { pub guild_id: Snowflake, pub members: Vec, @@ -165,7 +165,7 @@ pub struct GuildMembersChunk { impl WebSocketEvent for GuildMembersChunk {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-role-create +/// See pub struct GuildRoleCreate { pub guild_id: Snowflake, pub role: RoleObject, @@ -174,7 +174,7 @@ pub struct GuildRoleCreate { impl WebSocketEvent for GuildRoleCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-role-update +/// See pub struct GuildRoleUpdate { pub guild_id: Snowflake, pub role: RoleObject, @@ -183,7 +183,7 @@ pub struct GuildRoleUpdate { impl WebSocketEvent for GuildRoleUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-role-delete +/// See pub struct GuildRoleDelete { pub guild_id: Snowflake, pub role_id: Snowflake, @@ -192,7 +192,7 @@ pub struct GuildRoleDelete { impl WebSocketEvent for GuildRoleDelete {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-create +/// See pub struct GuildScheduledEventCreate { #[serde(flatten)] pub event: GuildScheduledEvent, @@ -201,7 +201,7 @@ pub struct GuildScheduledEventCreate { impl WebSocketEvent for GuildScheduledEventCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-update +/// See pub struct GuildScheduledEventUpdate { #[serde(flatten)] pub event: GuildScheduledEvent, @@ -210,7 +210,7 @@ pub struct GuildScheduledEventUpdate { impl WebSocketEvent for GuildScheduledEventUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-delete +/// See pub struct GuildScheduledEventDelete { #[serde(flatten)] pub event: GuildScheduledEvent, @@ -219,7 +219,7 @@ pub struct GuildScheduledEventDelete { impl WebSocketEvent for GuildScheduledEventDelete {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-add +/// See pub struct GuildScheduledEventUserAdd { pub guild_scheduled_event_id: Snowflake, pub user_id: Snowflake, @@ -229,7 +229,7 @@ pub struct GuildScheduledEventUserAdd { impl WebSocketEvent for GuildScheduledEventUserAdd {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-remove +/// See pub struct GuildScheduledEventUserRemove { pub guild_scheduled_event_id: Snowflake, pub user_id: Snowflake, diff --git a/src/types/events/integration.rs b/src/types/events/integration.rs index de55a5b..2423e78 100644 --- a/src/types/events/integration.rs +++ b/src/types/events/integration.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{Integration, Snowflake, WebSocketEvent}; #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#integration-create +/// See pub struct IntegrationCreate { #[serde(flatten)] pub integration: Integration, @@ -13,7 +13,7 @@ pub struct IntegrationCreate { impl WebSocketEvent for IntegrationCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#integration-update +/// See pub struct IntegrationUpdate { #[serde(flatten)] pub integration: Integration, @@ -23,7 +23,7 @@ pub struct IntegrationUpdate { impl WebSocketEvent for IntegrationUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#integration-delete +/// See pub struct IntegrationDelete { pub id: Snowflake, pub guild_id: Snowflake, diff --git a/src/types/events/interaction.rs b/src/types/events/interaction.rs index e77ee7c..304e7d4 100644 --- a/src/types/events/interaction.rs +++ b/src/types/events/interaction.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{Interaction, WebSocketEvent}; #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#interaction-create +/// See pub struct InteractionCreate { #[serde(flatten)] pub interaction: Interaction, diff --git a/src/types/events/invite.rs b/src/types/events/invite.rs index f04134d..674cc62 100644 --- a/src/types/events/invite.rs +++ b/src/types/events/invite.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{GuildInvite, Snowflake, WebSocketEvent}; #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#invite-create +/// See pub struct InviteCreate { #[serde(flatten)] pub invite: GuildInvite, @@ -12,7 +12,7 @@ pub struct InviteCreate { impl WebSocketEvent for InviteCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#invite-delete +/// See pub struct InviteDelete { pub channel_id: Snowflake, pub guild_id: Option, diff --git a/src/types/events/lazy_request.rs b/src/types/events/lazy_request.rs index 2fd98af..fd53183 100644 --- a/src/types/events/lazy_request.rs +++ b/src/types/events/lazy_request.rs @@ -13,7 +13,7 @@ use super::WebSocketEvent; /// Sent by the official client when switching to a guild or channel; /// After this, you should recieve message updates /// -/// See https://luna.gitlab.io/discord-unofficial-docs/lazy_guilds.html#op-14-lazy-request +/// See /// /// {"op":14,"d":{"guild_id":"848582562217590824","typing":true,"activities":true,"threads":true}} pub struct LazyRequest { diff --git a/src/types/events/message.rs b/src/types/events/message.rs index 5a67417..70f28f6 100644 --- a/src/types/events/message.rs +++ b/src/types/events/message.rs @@ -19,7 +19,7 @@ pub struct TypingStartEvent { impl WebSocketEvent for TypingStartEvent {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#message-create +/// See pub struct MessageCreate { #[serde(flatten)] message: Message, @@ -29,7 +29,7 @@ pub struct MessageCreate { } #[derive(Debug, Serialize, Deserialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#message-create-message-create-extra-fields +/// See pub struct MessageCreateUser { #[serde(flatten)] user: PublicUser, @@ -114,7 +114,7 @@ impl WebSocketEvent for MessageReactionRemoveEmoji {} /// /// Not documented anywhere unofficially /// -/// Apparently "Message ACK refers to marking a message as read for Discord's API." (https://github.com/Rapptz/discord.py/issues/1851) +/// Apparently "Message ACK refers to marking a message as read for Discord's API." () /// I suspect this is sent and recieved from the gateway to let clients on other devices know the user has read a message /// /// {"t":"MESSAGE_ACK","s":3,"op":0,"d":{"version":52,"message_id":"1107236673638633472","last_viewed":null,"flags":null,"channel_id":"967363950217936897"}} diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index 6333544..ed22a70 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -57,7 +57,7 @@ pub trait WebSocketEvent {} #[derive(Debug, Default, Serialize, Clone)] /// The payload used for sending events to the gateway /// -/// Similar to [GatewayReceivePayload], except we send a [Value] for d whilst we receive a [serde_json::value::RawValue] +/// Similar to [GatewayReceivePayload], except we send a [serde_json::value::Value] for d whilst we receive a [serde_json::value::RawValue] /// Also, we never need to send the event name pub struct GatewaySendPayload { #[serde(rename = "op")] @@ -76,9 +76,6 @@ impl WebSocketEvent for GatewaySendPayload {} #[derive(Debug, Default, Deserialize, Clone)] /// The payload used for receiving events from the gateway -/// -/// Similar to [GatewaySendPayload], except we send a [Value] for d whilst we receive a [serde_json::value::RawValue] -/// Also, we never need to sent the event name pub struct GatewayReceivePayload<'a> { #[serde(rename = "op")] pub op_code: u8, diff --git a/src/types/events/presence.rs b/src/types/events/presence.rs index ad06954..0aef27e 100644 --- a/src/types/events/presence.rs +++ b/src/types/events/presence.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// Sent by the client to update its status and presence; -/// See https://discord.com/developers/docs/topics/gateway-events#update-presence +/// See pub struct UpdatePresence { /// unix time of when the client went idle, or none if client is not idle pub since: Option, @@ -16,7 +16,7 @@ pub struct UpdatePresence { #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// Received to tell the client that a user updated their presence / status -/// See https://discord.com/developers/docs/topics/gateway-events#presence-update-presence-update-event-fields +/// See pub struct PresenceUpdate { pub user: PublicUser, #[serde(default)] diff --git a/src/types/events/ready.rs b/src/types/events/ready.rs index 9b6eab9..ea46b69 100644 --- a/src/types/events/ready.rs +++ b/src/types/events/ready.rs @@ -8,7 +8,7 @@ use crate::types::{Activity, GuildMember, PresenceUpdate, VoiceState}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// 1/2 half documented; /// Received after identifying, provides initial user info; -/// See https://discord.com/developers/docs/topics/gateway-events#ready; +/// See pub struct GatewayReady { pub analytics_token: Option, pub auth_session_id_hash: Option, @@ -16,7 +16,7 @@ pub struct GatewayReady { pub v: u8, pub user: User, - /// For bots these are [UnavailableGuild]s, for users they are [Guild] + /// For bots these are [crate::types::UnavailableGuild]s, for users they are [Guild] pub guilds: Vec, pub presences: Option>, pub sessions: Option>, diff --git a/src/types/events/relationship.rs b/src/types/events/relationship.rs index 441c74a..a1f75a5 100644 --- a/src/types/events/relationship.rs +++ b/src/types/events/relationship.rs @@ -2,7 +2,7 @@ use crate::types::{events::WebSocketEvent, Relationship, RelationshipType, Snowf use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize, Default)] -/// See https://github.com/spacebarchat/server/issues/204 +/// See pub struct RelationshipAdd { #[serde(flatten)] pub relationship: Relationship, @@ -12,7 +12,7 @@ pub struct RelationshipAdd { impl WebSocketEvent for RelationshipAdd {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://github.com/spacebarchat/server/issues/203 +/// See pub struct RelationshipRemove { pub id: Snowflake, #[serde(rename = "type")] diff --git a/src/types/events/request_members.rs b/src/types/events/request_members.rs index 2d537b9..526313b 100644 --- a/src/types/events/request_members.rs +++ b/src/types/events/request_members.rs @@ -2,7 +2,7 @@ use crate::types::{events::WebSocketEvent, Snowflake}; use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize, Default)] -/// See https://discord.com/developers/docs/topics/gateway-events#request-guild-members-request-guild-members-structure +/// See pub struct GatewayRequestGuildMembers { pub guild_id: Snowflake, pub query: Option, diff --git a/src/types/events/stage_instance.rs b/src/types/events/stage_instance.rs index 0fe487b..c2bbc46 100644 --- a/src/types/events/stage_instance.rs +++ b/src/types/events/stage_instance.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{StageInstance, WebSocketEvent}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#stage-instance-create +/// See pub struct StageInstanceCreate { #[serde(flatten)] pub stage_instance: StageInstance, @@ -12,7 +12,7 @@ pub struct StageInstanceCreate { impl WebSocketEvent for StageInstanceCreate {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#stage-instance-update +/// See pub struct StageInstanceUpdate { #[serde(flatten)] pub stage_instance: StageInstance, @@ -21,7 +21,7 @@ pub struct StageInstanceUpdate { impl WebSocketEvent for StageInstanceUpdate {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#stage-instance-delete +/// See pub struct StageInstanceDelete { #[serde(flatten)] pub stage_instance: StageInstance, diff --git a/src/types/events/thread.rs b/src/types/events/thread.rs index e8276e7..2faecf7 100644 --- a/src/types/events/thread.rs +++ b/src/types/events/thread.rs @@ -5,7 +5,7 @@ use crate::types::events::WebSocketEvent; use crate::types::Snowflake; #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#thread-create +/// See pub struct ThreadCreate { #[serde(flatten)] pub thread: Channel, @@ -14,7 +14,7 @@ pub struct ThreadCreate { impl WebSocketEvent for ThreadCreate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#thread-update +/// See pub struct ThreadUpdate { #[serde(flatten)] pub thread: Channel, @@ -23,7 +23,7 @@ pub struct ThreadUpdate { impl WebSocketEvent for ThreadUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#thread-delete +/// See pub struct ThreadDelete { #[serde(flatten)] pub thread: Channel, @@ -32,7 +32,7 @@ pub struct ThreadDelete { impl WebSocketEvent for ThreadDelete {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#thread-list-sync +/// See pub struct ThreadListSync { pub guild_id: Snowflake, pub channel_ids: Option>, @@ -43,7 +43,7 @@ pub struct ThreadListSync { impl WebSocketEvent for ThreadListSync {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#thread-member-update +/// See /// The inner payload is a thread member object with an extra field. pub struct ThreadMemberUpdate { #[serde(flatten)] @@ -54,7 +54,7 @@ pub struct ThreadMemberUpdate { impl WebSocketEvent for ThreadMemberUpdate {} #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#thread-members-update +/// See pub struct ThreadMembersUpdate { pub id: Snowflake, pub guild_id: Snowflake, diff --git a/src/types/events/user.rs b/src/types/events/user.rs index 18c8511..e3ce99a 100644 --- a/src/types/events/user.rs +++ b/src/types/events/user.rs @@ -5,7 +5,7 @@ use crate::types::events::WebSocketEvent; use crate::types::utils::Snowflake; #[derive(Debug, Default, Deserialize, Serialize, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#user-update; +/// See ; /// Sent to indicate updates to a user object; (name changes, discriminator changes, etc); pub struct UserUpdate { #[serde(flatten)] diff --git a/src/types/events/voice.rs b/src/types/events/voice.rs index 63e740a..ff13b73 100644 --- a/src/types/events/voice.rs +++ b/src/types/events/voice.rs @@ -16,7 +16,7 @@ pub struct UpdateVoiceState { impl WebSocketEvent for UpdateVoiceState {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#voice-state-update; +/// See ; /// /// Received from the server to indicate an update in a user's voice state (leave voice channel, join voice channel, mute, deafen, etc); /// @@ -29,7 +29,7 @@ pub struct VoiceStateUpdate { impl WebSocketEvent for VoiceStateUpdate {} #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#voice-server-update; +/// See ; /// /// Received to indicate which voice endpoint, token and guild_id to use; pub struct VoiceServerUpdate { diff --git a/src/types/events/webhooks.rs b/src/types/events/webhooks.rs index 3f0158e..518b332 100644 --- a/src/types/events/webhooks.rs +++ b/src/types/events/webhooks.rs @@ -5,7 +5,7 @@ use crate::types::Snowflake; use super::WebSocketEvent; #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#webhooks-update +/// See pub struct WebhooksUpdate { pub guild_id: Snowflake, pub channel_id: Snowflake, diff --git a/src/types/interfaces/status.rs b/src/types/interfaces/status.rs index c82e665..fadaf68 100644 --- a/src/types/interfaces/status.rs +++ b/src/types/interfaces/status.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] -/// See https://discord.com/developers/docs/topics/gateway-events#client-status-object +/// See pub struct ClientStatusObject { pub desktop: Option, pub mobile: Option, diff --git a/src/types/utils/snowflake.rs b/src/types/utils/snowflake.rs index 6176ea5..3a054b3 100644 --- a/src/types/utils/snowflake.rs +++ b/src/types/utils/snowflake.rs @@ -11,7 +11,7 @@ use sqlx::Type; const EPOCH: i64 = 1420070400000; /// Unique identifier including a timestamp. -/// See https://discord.com/developers/docs/reference#snowflakes +/// See #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "sqlx", derive(Type))] #[cfg_attr(feature = "sqlx", sqlx(transparent))] From a0d2fc82133a0e429345991f29cb801a21d5eba4 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:54:04 +0200 Subject: [PATCH 004/237] Add some docs --- src/api/auth/login.rs | 1 + src/api/auth/register.rs | 10 +--------- src/api/channels/channels.rs | 32 +++++--------------------------- 3 files changed, 7 insertions(+), 36 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index baae4ae..1109fb8 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -11,6 +11,7 @@ use crate::ratelimiter::ChorusRequest; use crate::types::{LoginResult, LoginSchema}; impl Instance { + /// Logs into an existing account on the spacebar server. pub async fn login_account(&mut self, login_schema: &LoginSchema) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/login"; let chorus_request = ChorusRequest { diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index e7b9d48..fa3d6c9 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -12,15 +12,7 @@ use crate::{ }; impl Instance { - /// Registers a new user on the Spacebar server. - /// - /// # Arguments - /// - /// * `register_schema` - The [`RegisterSchema`] that contains all the information that is needed to register a new user. - /// - /// # Errors - /// - /// * [`crate::errors::ChorusError`] - If the server does not respond. + /// Registers a new user on the server. pub async fn register_account( &mut self, register_schema: &RegisterSchema, diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 82662e3..9cb65a9 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -10,6 +10,7 @@ use crate::{ }; impl Channel { + /// Retrieves a channel from the server. pub async fn get(user: &mut UserMeta, channel_id: Snowflake) -> ChorusResult { let url = user.belongs_to.borrow().urls.api.clone(); let chorus_request = ChorusRequest { @@ -21,19 +22,7 @@ impl Channel { chorus_request.deserialize_response::(user).await } - /// Deletes a channel. - /// - /// # Arguments - /// - /// * `token` - A string slice that holds the authorization token. - /// * `url_api` - A string slice that holds the URL of the API. - /// * `channel` - A `Channel` object that represents the channel to be deleted. - /// * `limits_user` - A mutable reference to a `Limits` object that represents the user's rate limits. - /// * `limits_instance` - A mutable reference to a `Limits` object that represents the instance's rate limits. - /// - /// # Returns - /// - /// A `Result` that contains a `ChorusLibError` if an error occurred during the request, or `()` if the request was successful. + /// Deletes self. pub async fn delete(self, user: &mut UserMeta) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() @@ -48,20 +37,8 @@ impl Channel { chorus_request.handle_request_as_result(user).await } - /// Modifies a channel. - /// - /// # Arguments - /// - /// * `modify_data` - A `ChannelModifySchema` object that represents the modifications to be made to the channel. - /// * `token` - A string slice that holds the authorization token. - /// * `url_api` - A string slice that holds the URL of the API. - /// * `channel_id` - A string slice that holds the ID of the channel to be modified. - /// * `limits_user` - A mutable reference to a `Limits` object that represents the user's rate limits. - /// * `limits_instance` - A mutable reference to a `Limits` object that represents the instance's rate limits. - /// - /// # Returns - /// - /// A `Result` that contains a `Channel` object if the request was successful, or an `ChorusLibError` if an error occurred during the request. + /// Modifies a channel with the provided data. + /// Replaces self with the new channel object. pub async fn modify( &mut self, modify_data: ChannelModifySchema, @@ -84,6 +61,7 @@ impl Channel { Ok(()) } + /// Fetches recent messages from a channel. pub async fn messages( range: GetChannelMessagesSchema, channel_id: Snowflake, From 9246fd95042e8dbf2c63f444365404479a925772 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 22 Jul 2023 14:38:55 +0200 Subject: [PATCH 005/237] Add `GatewayHandle` to `UserMeta` --- src/instance.rs | 17 +++++++++++++---- tests/gateway.rs | 22 ++++++++++------------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index 0cd65f4..9795557 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::api::{Limit, LimitType}; use crate::errors::ChorusResult; +use crate::gateway::{Gateway, GatewayHandle}; use crate::ratelimiter::ChorusRequest; use crate::types::types::subconfigs::limits::rates::RateLimits; use crate::types::{GeneralConfiguration, User, UserSettings}; @@ -88,13 +89,14 @@ impl fmt::Display for Token { } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct UserMeta { pub belongs_to: Rc>, pub token: String, pub limits: Option>, pub settings: UserSettings, pub object: User, + pub gateway: GatewayHandle, } impl UserMeta { @@ -112,6 +114,7 @@ impl UserMeta { limits: Option>, settings: UserSettings, object: User, + gateway: GatewayHandle, ) -> UserMeta { UserMeta { belongs_to, @@ -119,19 +122,24 @@ impl UserMeta { limits, settings, object, + gateway, } } /// Creates a new 'shell' of a user. The user does not exist as an object, and exists so that you have /// a UserMeta object to make Rate Limited requests with. This is useful in scenarios like /// registering or logging in to the Instance, where you do not yet have a User object, but still - /// need to make a RateLimited request. - pub(crate) fn shell(instance: Rc>, token: String) -> UserMeta { + /// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify + /// first. + pub(crate) async fn shell(instance: Rc>, token: String) -> UserMeta { let settings = UserSettings::default(); let object = User::default(); + let wss_url = instance.borrow().urls.wss.clone(); + // Dummy gateway object + let gateway = Gateway::new(wss_url).await.unwrap(); UserMeta { - belongs_to: instance.clone(), token, + belongs_to: instance.clone(), limits: instance .borrow() .limits_information @@ -139,6 +147,7 @@ impl UserMeta { .map(|info| info.ratelimits.clone()), settings, object, + gateway, } } } diff --git a/tests/gateway.rs b/tests/gateway.rs index 199e14b..21a2018 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -8,7 +8,8 @@ use chorus::types::{self, Channel}; async fn test_gateway_establish() { let bundle = common::setup().await; - Gateway::new(bundle.urls.wss).await.unwrap(); + Gateway::new(bundle.urls.wss.clone()).await.unwrap(); + common::teardown(bundle).await } #[tokio::test] @@ -16,25 +17,21 @@ async fn test_gateway_establish() { async fn test_gateway_authenticate() { let bundle = common::setup().await; - let gateway = Gateway::new(bundle.urls.wss).await.unwrap(); + let gateway = Gateway::new(bundle.urls.wss.clone()).await.unwrap(); let mut identify = types::GatewayIdentifyPayload::common(); - identify.token = bundle.user.token; + identify.token = bundle.user.token.clone(); gateway.send_identify(identify).await; + common::teardown(bundle).await } #[tokio::test] async fn test_self_updating_structs() { let mut bundle = common::setup().await; - let gateway = Gateway::new(bundle.urls.wss).await.unwrap(); - let mut identify = types::GatewayIdentifyPayload::common(); - identify.token = bundle.user.token.clone(); - gateway.send_identify(identify).await; - let channel_receiver = gateway.observe(bundle.channel.clone()).await; - let received_channel = channel_receiver.borrow(); - assert_eq!(*received_channel, bundle.channel); - drop(received_channel); + let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; + let received_channel = channel_updater.borrow().clone(); + assert_eq!(received_channel, bundle.channel); let channel = &mut bundle.channel; let modify_data = types::ChannelModifySchema { name: Some("beepboop".to_string()), @@ -43,6 +40,7 @@ async fn test_self_updating_structs() { Channel::modify(channel, modify_data, channel.id, &mut bundle.user) .await .unwrap(); - let received_channel = channel_receiver.borrow(); + let received_channel = channel_updater.borrow(); assert_eq!(received_channel.name.as_ref().unwrap(), "beepboop"); + common::teardown(bundle).await } From 25704f6dda9624053c1e0611d98cd40f05c895e8 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 22 Jul 2023 14:39:36 +0200 Subject: [PATCH 006/237] Make user::shell async due to gateway add --- src/api/auth/login.rs | 11 +++++++++-- src/api/auth/register.rs | 10 +++++++++- src/api/users/users.rs | 5 +++-- tests/common/mod.rs | 13 ++++++++++++- tests/invites.rs | 8 +++----- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index baae4ae..68604d9 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -6,9 +6,10 @@ use serde_json::to_string; use crate::api::LimitType; use crate::errors::ChorusResult; +use crate::gateway::Gateway; use crate::instance::{Instance, UserMeta}; use crate::ratelimiter::ChorusRequest; -use crate::types::{LoginResult, LoginSchema}; +use crate::types::{GatewayIdentifyPayload, LoginResult, LoginSchema}; impl Instance { pub async fn login_account(&mut self, login_schema: &LoginSchema) -> ChorusResult { @@ -22,7 +23,8 @@ impl Instance { // We do not have a user yet, and the UserRateLimits will not be affected by a login // request (since login is an instance wide limit), which is why we are just cloning the // instances' limits to pass them on as user_rate_limits later. - let mut shell = UserMeta::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()); + let mut shell = + UserMeta::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; let login_result = chorus_request .deserialize_response::(&mut shell) .await?; @@ -30,12 +32,17 @@ impl Instance { if self.limits_information.is_some() { self.limits_information.as_mut().unwrap().ratelimits = shell.limits.clone().unwrap(); } + let mut identify = GatewayIdentifyPayload::common(); + let gateway = Gateway::new(self.urls.wss.clone()).await.unwrap(); + identify.token = login_result.token.clone(); + gateway.send_identify(identify).await; let user = UserMeta::new( Rc::new(RefCell::new(self.clone())), login_result.token, self.clone_limits_if_some(), login_result.settings, object, + gateway, ); Ok(user) } diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index a6849cc..e818d82 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -3,6 +3,8 @@ use std::{cell::RefCell, rc::Rc}; use reqwest::Client; use serde_json::to_string; +use crate::gateway::Gateway; +use crate::types::GatewayIdentifyPayload; use crate::{ api::policies::instance::LimitType, errors::ChorusResult, @@ -35,7 +37,8 @@ impl Instance { // We do not have a user yet, and the UserRateLimits will not be affected by a login // request (since register is an instance wide limit), which is why we are just cloning // the instances' limits to pass them on as user_rate_limits later. - let mut shell = UserMeta::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()); + let mut shell = + UserMeta::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; let token = chorus_request .deserialize_response::(&mut shell) .await? @@ -45,12 +48,17 @@ impl Instance { } let user_object = self.get_user(token.clone(), None).await.unwrap(); let settings = UserMeta::get_settings(&token, &self.urls.api.clone(), self).await?; + let mut identify = GatewayIdentifyPayload::common(); + let gateway = Gateway::new(self.urls.wss.clone()).await.unwrap(); + identify.token = token.clone(); + gateway.send_identify(identify).await; let user = UserMeta::new( Rc::new(RefCell::new(self.clone())), token.clone(), self.clone_limits_if_some(), settings, user_object, + gateway, ); Ok(user) } diff --git a/src/api/users/users.rs b/src/api/users/users.rs index bd46a36..af6d2ce 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -122,7 +122,8 @@ impl User { let request: reqwest::RequestBuilder = Client::new() .get(format!("{}/users/@me/settings/", url_api)) .bearer_auth(token); - let mut user = UserMeta::shell(Rc::new(RefCell::new(instance.clone())), token.clone()); + let mut user = + UserMeta::shell(Rc::new(RefCell::new(instance.clone())), token.clone()).await; let chorus_request = ChorusRequest { request, limit_type: LimitType::Global, @@ -151,7 +152,7 @@ impl Instance { This function is a wrapper around [`User::get`]. */ pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult { - let mut user = UserMeta::shell(Rc::new(RefCell::new(self.clone())), token); + let mut user = UserMeta::shell(Rc::new(RefCell::new(self.clone())), token).await; let result = User::get(&mut user, id).await; if self.limits_information.is_some() { self.limits_information.as_mut().unwrap().ratelimits = diff --git a/tests/common/mod.rs b/tests/common/mod.rs index fc4a19c..747a8cd 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,3 +1,4 @@ +use chorus::gateway::Gateway; use chorus::{ instance::{Instance, UserMeta}, types::{ @@ -18,8 +19,8 @@ pub(crate) struct TestBundle { pub channel: Channel, } +#[allow(unused)] impl TestBundle { - #[allow(unused)] pub(crate) async fn create_user(&mut self, username: &str) -> UserMeta { let register_schema = RegisterSchema { username: username.to_string(), @@ -32,6 +33,16 @@ impl TestBundle { .await .unwrap() } + pub(crate) async fn clone_user_without_gateway(&self) -> UserMeta { + UserMeta { + belongs_to: self.user.belongs_to.clone(), + token: self.user.token.clone(), + limits: self.user.limits.clone(), + settings: self.user.settings.clone(), + object: self.user.object.clone(), + gateway: Gateway::new(self.instance.urls.wss.clone()).await.unwrap(), + } + } } // Set up a test by creating an Instance and a User. Reduces Test boilerplate. diff --git a/tests/invites.rs b/tests/invites.rs index b6206b9..d19be61 100644 --- a/tests/invites.rs +++ b/tests/invites.rs @@ -1,14 +1,12 @@ -use chorus::types::CreateChannelInviteSchema; - mod common; - +use chorus::types::CreateChannelInviteSchema; #[tokio::test] async fn create_accept_invite() { let mut bundle = common::setup().await; let channel = bundle.channel.clone(); - let mut user = bundle.user.clone(); - let create_channel_invite_schema = CreateChannelInviteSchema::default(); let mut other_user = bundle.create_user("testuser1312").await; + let user = &mut bundle.user; + let create_channel_invite_schema = CreateChannelInviteSchema::default(); assert!(chorus::types::Guild::get(bundle.guild.id, &mut other_user) .await .is_err()); From d0547cb1f01bf2f545145ccf5e8d37695e33b712 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Fri, 28 Jul 2023 18:45:40 +0200 Subject: [PATCH 007/237] Better docs --- src/api/channels/channels.rs | 2 +- src/api/channels/messages.rs | 8 +-- src/api/channels/permissions.rs | 20 ------- src/api/channels/reactions.rs | 92 ++++++++++++++------------------- src/api/guilds/guilds.rs | 71 ++++--------------------- 5 files changed, 55 insertions(+), 138 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index a8bc7ee..db94056 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -39,7 +39,7 @@ impl Channel { } /// Modifies a channel with the provided data. - /// Replaces self with the new channel object. + /// Returns the new Channel. pub async fn modify( &self, modify_data: ChannelModifySchema, diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 63ebebc..9c06f6f 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -10,7 +10,8 @@ use crate::ratelimiter::ChorusRequest; use crate::types::{Message, MessageSendSchema, Snowflake}; impl Message { - /// Sends a message to the Spacebar server. + /// Sends a message in the channel with the provided channel_id. + /// Returns the sent message. pub async fn send( user: &mut UserMeta, channel_id: Snowflake, @@ -68,14 +69,15 @@ impl Message { } impl UserMeta { - /// Sends a message to the Spacebar server. + /// Sends a message in the channel with the provided channel_id. + /// Returns the sent message. /// # Notes /// Shorthand call for Message::send() pub async fn send_message( &mut self, message: MessageSendSchema, channel_id: Snowflake, - ) -> ChorusResult { + ) -> ChorusResult { Message::send(self, channel_id, message).await } } diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index bc666ff..57feb5d 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -11,16 +11,6 @@ use crate::{ impl types::Channel { /// Edits the permission overwrites for a channel. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `channel_id` - A string slice representing the ID of the channel. - /// * `overwrite` - A [`PermissionOverwrite`] instance representing the new permission overwrites. - /// - /// # Returns - /// - /// This function returns a result that is either [`Ok(())`] if the request is successful, or an [`Err(ChorusLibError)`]. pub async fn edit_permissions( user: &mut UserMeta, channel_id: Snowflake, @@ -48,16 +38,6 @@ impl types::Channel { } /// Deletes a permission overwrite for a channel. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `channel_id` - A string slice representing the ID of the channel. - /// * `overwrite_id` - A string slice representing the ID of the permission overwrite to delete. - /// - /// # Returns - /// - /// This function returns a Result that is either [`Ok(())`] if the request is successfulm or an [`Err(ChorusLibError)`]. pub async fn delete_permission( user: &mut UserMeta, channel_id: Snowflake, diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index fe1e57f..467af56 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -16,12 +16,11 @@ pub struct ReactionMeta { impl ReactionMeta { /// Deletes all reactions for a message. + /// /// This endpoint requires the `MANAGE_MESSAGES` permission to be present on the current user. - /// # Arguments - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// # Returns - /// A `Result` [`()`] [`crate::errors::ChorusError`] if something went wrong. + /// /// Fires a `Message Reaction Remove All` Gateway event. + /// /// # Reference /// See pub async fn delete_all(&self, user: &mut UserMeta) -> ChorusResult<()> { @@ -39,13 +38,10 @@ impl ReactionMeta { } /// Gets a list of users that reacted with a specific emoji to a message. - /// # Arguments - /// * `emoji` - A string slice containing the emoji to search for. The emoji must be URL Encoded or - /// the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the - /// format name:id with the emoji name and emoji id. - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// # Returns - /// A Result that is [`Err(crate::errors::ChorusLibError)`] if something went wrong. + /// + /// The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. + /// To use custom emoji, the format of the emoji string must be name:id. + /// /// # Reference /// See pub async fn get(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult> { @@ -65,16 +61,15 @@ impl ReactionMeta { .await } - /// Deletes all the reactions for a given `emoji` on a message. This endpoint requires the - /// MANAGE_MESSAGES permission to be present on the current user. - /// # Arguments - /// * `emoji` - A string slice containing the emoji to delete. The `emoji` must be URL Encoded or - /// the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the - /// format name:id with the emoji name and emoji id. - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// # Returns - /// A Result that is [`Err(crate::errors::ChorusLibError)`] if something went wrong. - /// Fires a `Message Reaction Remove Emoji` Gateway event. + /// Deletes all the reactions for a given emoji on a message. + /// + /// This endpoint requires the MANAGE_MESSAGES permission. + /// + /// The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. + /// To use custom emoji, the format of the emoji string must be name:id. + /// + /// Fires the `Message Reaction Remove Emoji` Gateway event. + /// /// # Reference /// See pub async fn delete_emoji(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { @@ -92,21 +87,18 @@ impl ReactionMeta { chorus_request.handle_request_as_result(user).await } - /// Create a reaction for the message. - /// This endpoint requires the READ_MESSAGE_HISTORY permission - /// to be present on the current user. Additionally, if nobody else has reacted to the message using - /// this emoji, this endpoint requires the ADD_REACTIONS permission to be present on the current - /// user. - /// # Arguments - /// * `emoji` - A string slice containing the emoji to delete. The `emoji` must be URL Encoded or - /// the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the - /// format name:id with the emoji name and emoji id. - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// # Returns - /// A `Result` containing [`()`] or a [`crate::errors::ChorusError`]. + /// Create a reaction on a message. + /// + /// This endpoint requires the READ_MESSAGE_HISTORY permission. + /// + /// Additionally, if nobody else has reacted to the message using this emoji, + /// this endpoint requires the ADD_REACTIONS permission. + /// + /// The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. + /// To use custom emoji, the format of the emoji string must be name:id. + /// /// # Reference /// See - /// pub async fn create(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me/", @@ -122,15 +114,13 @@ impl ReactionMeta { chorus_request.handle_request_as_result(user).await } - /// Delete a reaction the current user has made for the message. - /// # Arguments - /// * `emoji` - A string slice containing the emoji to delete. The `emoji` must be URL Encoded or - /// the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the - /// format name:id with the emoji name and emoji id. - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// # Returns - /// A `Result` containing [`()`] or a [`crate::errors::ChorusError`]. + /// Deletes a reaction the current user has made to the message. + /// + /// The reaction emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. + /// To use custom emoji, the format of the emoji string must be name:id. + /// /// Fires a `Message Reaction Remove` Gateway event. + /// /// # Reference /// See pub async fn remove(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { @@ -148,17 +138,15 @@ impl ReactionMeta { chorus_request.handle_request_as_result(user).await } - /// Delete a user's reaction to a message. - /// This endpoint requires the MANAGE_MESSAGES permission to be present on the current user. - /// # Arguments - /// * `user_id` - ID of the user whose reaction is to be deleted. - /// * `emoji` - A string slice containing the emoji to delete. The `emoji` must be URL Encoded or - /// the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the - /// format name:id with the emoji name and emoji id. - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// # Returns - /// A [`ChorusResult`] containing [`()`] or a [`crate::errors::ChorusError`]. + /// Deletes a user's reaction to a message. + /// + /// This endpoint requires the MANAGE_MESSAGES permission. + /// + /// The reaction emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. + /// To use custom emoji, the format of the emoji string must be name:id. + /// /// Fires a Message Reaction Remove Gateway event. + /// /// # Reference /// See pub async fn delete_user( diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 3654698..d4abcab 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -11,22 +11,7 @@ use crate::types::Snowflake; use crate::types::{Channel, ChannelCreateSchema, Guild, GuildCreateSchema}; impl Guild { - /// Creates a new guild with the given parameters. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to the user creating the guild. - /// * `instance` - A mutable reference to the instance where the guild will be created. - /// * `guild_create_schema` - A reference to the schema containing the guild creation parameters. - /// - /// # Returns - /// - /// A `Result` containing the object of the newly created guild, or an error if the request fails. - /// - /// # Errors - /// - /// Returns an `ChorusLibError` if the request fails. - /// + /// Creates a new guild. pub async fn create( user: &mut UserMeta, guild_create_schema: GuildCreateSchema, @@ -42,17 +27,7 @@ impl Guild { chorus_request.deserialize_response::(user).await } - /// Deletes a guild. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a `User` instance. - /// * `instance` - A mutable reference to an `Instance` instance. - /// * `guild_id` - ID of the guild to delete. - /// - /// # Returns - /// - /// An `Result` containing an `ChorusLibError` if an error occurred during the request, otherwise `()`. + /// Deletes a guild by its id. /// /// # Example /// @@ -61,9 +36,9 @@ impl Guild { /// let mut instance = Instance::new(); /// let guild_id = String::from("1234567890"); /// - /// match Guild::delete(&mut user, &mut instance, guild_id) { - /// Some(e) => println!("Error deleting guild: {:?}", e), - /// None => println!("Guild deleted successfully"), + /// match Guild::delete(&mut user, guild_id) { + /// Err(e) => println!("Error deleting guild: {:?}", e), + /// Ok(_) => println!("Guild deleted successfully"), /// } /// ``` pub async fn delete(user: &mut UserMeta, guild_id: Snowflake) -> ChorusResult<()> { @@ -81,19 +56,7 @@ impl Guild { chorus_request.handle_request_as_result(user).await } - /// Sends a request to create a new channel in the guild. - /// - /// # Arguments - /// - /// * `url_api` - The base URL for the Discord API. - /// * `token` - A Discord bot token. - /// * `schema` - A `ChannelCreateSchema` struct containing the properties of the new channel. - /// * `limits_user` - A mutable reference to a `Limits` struct containing the user's rate limits. - /// * `limits_instance` - A mutable reference to a `Limits` struct containing the instance's rate limits. - /// - /// # Returns - /// - /// A `Result` containing a `reqwest::Response` if the request was successful, or an `ChorusLibError` if there was an error. + /// Creates a new channel in a guild. pub async fn create_channel( &self, user: &mut UserMeta, @@ -102,15 +65,7 @@ impl Guild { Channel::create(user, self.id, schema).await } - /// Returns a `Result` containing a vector of `Channel` structs if the request was successful, or an `ChorusLibError` if there was an error. - /// - /// # Arguments - /// - /// * `url_api` - A string slice that holds the URL of the API. - /// * `token` - A string slice that holds the authorization token. - /// * `limits_user` - A mutable reference to a `Limits` struct containing the user's rate limits. - /// * `limits_instance` - A mutable reference to a `Limits` struct containing the instance's rate limits. - /// + // TODO: Docs: What is this endpoint? pub async fn channels(&self, user: &mut UserMeta) -> ChorusResult> { let chorus_request = ChorusRequest { request: Client::new() @@ -141,16 +96,8 @@ impl Guild { }; } - /// Returns a `Result` containing a `Guild` struct if the request was successful, or an `ChorusLibError` if there was an error. - /// - /// # Arguments - /// - /// * `url_api` - A string slice that holds the URL of the API. - /// * `guild_id` - ID of the guild. - /// * `token` - A string slice that holds the authorization token. - /// * `limits_user` - A mutable reference to a `Limits` struct containing the user's rate limits. - /// * `limits_instance` - A mutable reference to a `Limits` struct containing the instance's rate limits. - /// + // TODO: Check if these docs are correct, Im not sure what this endpoint is + /// Fetches a given guild. pub async fn get(guild_id: Snowflake, user: &mut UserMeta) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() From 8eb2e2008c936a3a383cd476b5ecd265841e3cfc Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Fri, 28 Jul 2023 18:57:35 +0200 Subject: [PATCH 008/237] Remove the todos from the last commit --- src/api/guilds/guilds.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index d4abcab..97286d8 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -65,7 +65,7 @@ impl Guild { Channel::create(user, self.id, schema).await } - // TODO: Docs: What is this endpoint? + /// Returns a list of the guild's channels pub async fn channels(&self, user: &mut UserMeta) -> ChorusResult> { let chorus_request = ChorusRequest { request: Client::new() @@ -96,8 +96,7 @@ impl Guild { }; } - // TODO: Check if these docs are correct, Im not sure what this endpoint is - /// Fetches a given guild. + /// Fetches a guild by its id. pub async fn get(guild_id: Snowflake, user: &mut UserMeta) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() From 83d4ffc4e84397df89a1a2d40a4ac4d9ebc08d18 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 10:23:04 +0200 Subject: [PATCH 009/237] Moar docs --- src/api/guilds/guilds.rs | 15 +------- src/api/guilds/member.rs | 34 +---------------- src/api/guilds/roles.rs | 54 ++------------------------- src/api/invites/mod.rs | 23 ++++++++++-- src/api/policies/instance/instance.rs | 2 - src/api/users/guilds.rs | 4 +- src/api/users/relationships.rs | 49 +++++++----------------- src/api/users/users.rs | 51 ++++++++----------------- src/instance.rs | 8 ++++ src/lib.rs | 13 ++++--- tests/invites.rs | 2 +- 11 files changed, 70 insertions(+), 185 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 97286d8..9b9d87f 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -114,20 +114,7 @@ impl Guild { } impl Channel { - /// Sends a request to create a new channel in a guild. - /// - /// # Arguments - /// - /// * `token` - A Discord bot token. - /// * `url_api` - The base URL for the Discord API. - /// * `guild_id` - The ID of the guild where the channel will be created. - /// * `schema` - A `ChannelCreateSchema` struct containing the properties of the new channel. - /// * `limits_user` - A mutable reference to a `Limits` struct containing the user's rate limits. - /// * `limits_instance` - A mutable reference to a `Limits` struct containing the instance's rate limits. - /// - /// # Returns - /// - /// A `Result` containing a `reqwest::Response` if the request was successful, or an `ChorusLibError` if there was an error. + /// Creates a new channel in a guild. pub async fn create( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index c7e26b9..1cf1a08 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -9,17 +9,7 @@ use crate::{ }; impl types::GuildMember { - /// Retrieves a guild member by their ID. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `guild_id` - The ID of the guild. - /// * `member_id` - The ID of the member. - /// - /// # Returns - /// - /// A [`ChorusResult`] containing a [`GuildMember`] if the request succeeds. + /// Retrieves a guild member. pub async fn get( user: &mut UserMeta, guild_id: Snowflake, @@ -41,17 +31,6 @@ impl types::GuildMember { } /// Adds a role to a guild member. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a `UserMeta` instance. - /// * `guild_id` - The ID of the guild. - /// * `member_id` - The ID of the member. - /// * `role_id` - The ID of the role to add. - /// - /// # Returns - /// - /// A [`ChorusResult`] containing a [`crate::errors::ChorusError`] if the request fails, or `()` if the request succeeds. pub async fn add_role( user: &mut UserMeta, guild_id: Snowflake, @@ -73,17 +52,6 @@ impl types::GuildMember { } /// Removes a role from a guild member. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a `UserMeta` instance. - /// * `guild_id` - The ID of the guild. - /// * `member_id` - The ID of the member. - /// * `role_id` - The ID of the role to remove. - /// - /// # Returns - /// - /// A [`ChorusResult`] containing a [`crate::errors::ChorusError`] if the request fails, or `()` if the request succeeds. pub async fn remove_role( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index f8cade9..81aca03 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -10,16 +10,9 @@ use crate::{ }; impl types::RoleObject { - /// Retrieves all roles for a given guild. + /// Retrieves a list of roles for a given guild. /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `guild_id` - The ID of the guild to retrieve roles from. - /// - /// # Returns - /// - /// An `Option` containing a `Vec` of [`RoleObject`]s if roles were found, or `None` if no roles were found. + /// Returns Ok(None) if the guild has no roles. pub async fn get_all( user: &mut UserMeta, guild_id: Snowflake, @@ -44,16 +37,6 @@ impl types::RoleObject { } /// Retrieves a single role for a given guild. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `guild_id` - The ID of the guild to retrieve the role from. - /// * `role_id` - The ID of the role to retrieve. - /// - /// # Returns - /// - /// A `Result` containing the retrieved [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. pub async fn get( user: &mut UserMeta, guild_id: Snowflake, @@ -75,16 +58,6 @@ impl types::RoleObject { } /// Creates a new role for a given guild. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `guild_id` - The ID of the guild to create the role in. - /// * `role_create_schema` - A [`RoleCreateModifySchema`] instance containing the properties of the role to be created. - /// - /// # Returns - /// - /// A `Result` containing the newly created [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. pub async fn create( user: &mut UserMeta, guild_id: Snowflake, @@ -109,17 +82,7 @@ impl types::RoleObject { .await } - /// Updates the position of a role in the guild's hierarchy. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `guild_id` - The ID of the guild to update the role position in. - /// * `role_position_update_schema` - A [`RolePositionUpdateSchema`] instance containing the new position of the role. - /// - /// # Returns - /// - /// A `Result` containing the updated [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. + /// Updates the position of a role in a given guild's hierarchy. pub async fn position_update( user: &mut UserMeta, guild_id: Snowflake, @@ -147,17 +110,6 @@ impl types::RoleObject { } /// Updates a role in a guild. - /// - /// # Arguments - /// - /// * `user` - A mutable reference to a [`UserMeta`] instance. - /// * `guild_id` - The ID of the guild to update the role in. - /// * `role_id` - The ID of the role to update. - /// * `role_create_schema` - A [`RoleCreateModifySchema`] instance containing the new properties of the role. - /// - /// # Returns - /// - /// A `Result` containing the updated [`RoleObject`] if successful, or a [`ChorusError`] if the request fails or if the response is invalid. pub async fn update( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index b766a5b..343f44d 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -7,9 +7,11 @@ use crate::ratelimiter::ChorusRequest; use crate::types::{CreateChannelInviteSchema, GuildInvite, Invite, Snowflake}; impl UserMeta { - /// # Arguments - /// - invite_code: The invite code to accept the invite for. - /// - session_id: The session ID that is accepting the invite, required for guest invites. + /// Accepts an invite to a guild, group DM, or DM. + /// + /// Note that the session ID is required for guest invites. + /// + /// May fire a Guild Create, Channel Create, and/or Relationship Add Gateway event. /// /// # Reference: /// Read @@ -35,7 +37,13 @@ impl UserMeta { } request.deserialize_response::(self).await } + + /// Creates a new friend invite. + /// /// Note: Spacebar does not yet implement this endpoint. + /// + /// # Reference: + /// Read pub async fn create_user_invite(&mut self, code: Option<&str>) -> ChorusResult { ChorusRequest { request: Client::new() @@ -51,7 +59,14 @@ impl UserMeta { .await } - pub async fn create_guild_invite( + /// Creates a new invite for a guild channel or group DM. + /// + /// # Guild Channels + /// For guild channels, the endpoint + /// requires the CREATE_INSTANT_INVITE permission. + /// + /// Guild channel invites also fire an Invite Create Gateway event. + pub async fn create_channel_invite( &mut self, create_channel_invite_schema: CreateChannelInviteSchema, channel_id: Snowflake, diff --git a/src/api/policies/instance/instance.rs b/src/api/policies/instance/instance.rs index d015778..ae6e5d5 100644 --- a/src/api/policies/instance/instance.rs +++ b/src/api/policies/instance/instance.rs @@ -6,8 +6,6 @@ use crate::types::GeneralConfiguration; impl Instance { /// Gets the instance policies schema. - /// # Errors - /// [`ChorusError`] - If the request fails. pub async fn general_configuration_schema(&self) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/policies/instance/"; let request = match self.client.get(&endpoint_url).send().await { diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index 735ed9e..dd52507 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -7,11 +7,11 @@ use crate::ratelimiter::ChorusRequest; use crate::types::Snowflake; impl UserMeta { - /// # Arguments: - /// - lurking: Whether the user is lurking in the guild + /// Leaves a given guild. /// /// # Reference: /// Read + // TODO: Docs: What is lurking here? pub async fn leave_guild(&mut self, guild_id: &Snowflake, lurking: bool) -> ChorusResult<()> { ChorusRequest { request: Client::new() diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index a864706..a5afaac 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -12,14 +12,10 @@ use crate::{ }; impl UserMeta { - /// Retrieves the mutual relationships between the authenticated user and the specified user. + /// Retrieves a list of mutual friends between the authenticated user and a given user. /// - /// # Arguments - /// - /// * `user_id` - ID of the user to retrieve the mutual relationships with. - /// - /// # Returns - /// This function returns a [`ChorusResult>`]. + /// # Reference + /// See pub async fn get_mutual_relationships( &mut self, user_id: Snowflake, @@ -38,10 +34,10 @@ impl UserMeta { .await } - /// Retrieves the authenticated user's relationships. + /// Retrieves the user's relationships. /// - /// # Returns - /// This function returns a [`ChorusResult>`]. + /// # Reference + /// See pub async fn get_relationships(&mut self) -> ChorusResult> { let url = format!( "{}/users/@me/relationships/", @@ -58,12 +54,8 @@ impl UserMeta { /// Sends a friend request to a user. /// - /// # Arguments - /// - /// * `schema` - A [`FriendRequestSendSchema`] struct that holds the information about the friend request to be sent. - /// - /// # Returns - /// This function returns a [`ChorusResult`]. + /// # Reference + /// See pub async fn send_friend_request( &mut self, schema: FriendRequestSendSchema, @@ -80,20 +72,9 @@ impl UserMeta { chorus_request.handle_request_as_result(self).await } - /// Modifies the relationship between the authenticated user and the specified user. + /// Modifies the relationship between the authenticated user and a given user. /// - /// # Arguments - /// - /// * `user_id` - ID of the user to modify the relationship with. - /// * `relationship_type` - A [`RelationshipType`] enum that specifies the type of relationship to modify. - /// * [`RelationshipType::None`]: Removes the relationship between the two users. - /// * [`RelationshipType::Friends`] | [`RelationshipType::Incoming`] | [`RelationshipType::Outgoing`]: - /// Either accepts an incoming friend request, or sends a new friend request, if there is no - /// incoming friend request from the specified `user_id`. - /// * [`RelationshipType::Blocked`]: Blocks the specified user_id. - /// - /// # Returns - /// This function returns an [`ChorusResult`]. + /// Can be used to unfriend users, accept or send friend requests and block or unblock users. pub async fn modify_user_relationship( &mut self, user_id: Snowflake, @@ -144,14 +125,10 @@ impl UserMeta { } } - /// Removes the relationship between the authenticated user and the specified user. + /// Removes the relationship between the authenticated user and a given user. /// - /// # Arguments - /// - /// * `user_id` - ID of the user to remove the relationship with. - /// - /// # Returns - /// This function returns a [`ChorusResult`]. + /// # Reference + /// See pub async fn remove_relationship(&mut self, user_id: Snowflake) -> ChorusResult<()> { let url = format!( "{}/users/@me/relationships/{}/", diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 9e7d2af..f673ee3 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -12,21 +12,18 @@ use crate::{ }; impl UserMeta { - /// Get a user object by id, or get the current user. + /// Gets a user by id, or if the id is None, gets the current user. /// - /// # Arguments - /// - /// * `token` - A valid access token for the API. - /// * `url_api` - The URL to the API. - /// * `id` - The id of the user that will be retrieved. If this is None, the current user will be retrieved. - /// - /// # Errors - /// - /// * [`ChorusError`] - If the request fails. + /// # Notes + /// This function is a wrapper around [`User::get`]. pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { User::get(user, id).await } + /// Gets the user's settings. + /// + /// # Notes + /// This functions is a wrapper around [`User::get_settings`]. pub async fn get_settings( token: &String, url_api: &String, @@ -35,15 +32,7 @@ impl UserMeta { User::get_settings(token, url_api, instance).await } - /// Modify the current user's `UserObject`. - /// - /// # Arguments - /// - /// * `modify_schema` - A `UserModifySchema` object containing the fields to modify. - /// - /// # Errors - /// - /// Returns an [`ChorusError`] if the request fails or if a password is required but not provided. + /// Modifies the current user's representation. (See [`User`]) pub async fn modify(&mut self, modify_schema: UserModifySchema) -> ChorusResult { if modify_schema.new_password.is_some() || modify_schema.email.is_some() @@ -67,15 +56,7 @@ impl UserMeta { Ok(user_updated) } - /// Sends a request to the server which deletes the user from the Instance. - /// - /// # Arguments - /// - /// * `self` - The `User` object to delete. - /// - /// # Returns - /// - /// Returns `()` if the user was successfully deleted, or a [`ChorusError`] if an error occurred. + /// Deletes the user from the Instance. pub async fn delete(mut self) -> ChorusResult<()> { let request = Client::new() .post(format!( @@ -92,6 +73,7 @@ impl UserMeta { } impl User { + /// Gets a user by id, or if the id is None, gets the current user. pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { let url_api = user.belongs_to.borrow().urls.api.clone(); let url = if id.is_none() { @@ -113,6 +95,7 @@ impl User { } } + /// Gets the user's settings. pub async fn get_settings( token: &String, url_api: &String, @@ -140,14 +123,10 @@ impl User { } impl Instance { - // Get a user object by id, or get the current user. - // # Arguments - // * `token` - A valid access token for the API. - // * `id` - The id of the user that will be retrieved. If this is None, the current user will be retrieved. - // # Errors - // * [`ChorusError`] - If the request fails. - // # Notes - // This function is a wrapper around [`User::get`]. + /// Gets a user by id, or if the id is None, gets the current user. + /// + /// # Notes + /// This function is a wrapper around [`User::get`]. pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult { let mut user = UserMeta::shell(Rc::new(RefCell::new(self.clone())), token).await; let result = User::get(&mut user, id).await; diff --git a/src/instance.rs b/src/instance.rs index 2360390..f034513 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -83,6 +83,9 @@ impl fmt::Display for Token { } #[derive(Debug)] +/// A UserMeta is a representation of an authenticated user on an [Instance]. +/// It is used for most authenticated actions on a Spacebar server. +/// It also has its own [Gateway] connection. pub struct UserMeta { pub belongs_to: Rc>, pub token: String, @@ -101,6 +104,11 @@ impl UserMeta { self.token = token; } + /// Creates a new [UserMeta] from existing data. + /// + /// # Notes + /// This isn't the prefered way to create a UserMeta. + /// See [Instance::login_account] and [Instance::register_account] instead. pub fn new( belongs_to: Rc>, token: String, diff --git a/src/lib.rs b/src/lib.rs index 5b14544..8315a4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,8 +16,8 @@ pub mod types; pub mod voice; #[derive(Clone, Default, Debug, PartialEq, Eq)] -/// A URLBundle is a struct which bundles together the API-, Gateway- and CDN-URLs of a Spacebar -/// instance. +/// A URLBundle bundles together the API-, Gateway- and CDN-URLs of a Spacebar instance. +/// /// # Notes /// All the urls can be found on the /api/policies/instance/domains endpoint of a spacebar server pub struct UrlBundle { @@ -25,7 +25,7 @@ pub struct UrlBundle { /// Ex: `https://old.server.spacebar.chat/api` pub api: String, /// The gateway websocket url. - /// Note that because this is a websocket url, it will always start with `wss://` + /// Note that because this is a websocket url, it will always start with `wss://` or `ws://` /// Ex: `wss://gateway.old.server.spacebar.chat` pub wss: String, /// The CDN's url. @@ -42,9 +42,10 @@ impl UrlBundle { } } - /// parse(url: String) parses a URL using the Url library and formats it in a standardized - /// way. If no protocol is given, HTTP (not HTTPS) is assumed. - /// # Example: + /// Parses a URL using the Url library and formats it in a standardized way. + /// If no protocol is given, HTTP (not HTTPS) is assumed. + /// + /// # Examples: /// ```rs /// let url = parse_url("localhost:3000"); /// ``` diff --git a/tests/invites.rs b/tests/invites.rs index d19be61..e25fea5 100644 --- a/tests/invites.rs +++ b/tests/invites.rs @@ -11,7 +11,7 @@ async fn create_accept_invite() { .await .is_err()); let invite = user - .create_guild_invite(create_channel_invite_schema, channel.id) + .create_channel_invite(create_channel_invite_schema, channel.id) .await .unwrap(); From 1e81a2682f37f857bb5566c1fb23167f17d1e1ed Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 11:00:28 +0200 Subject: [PATCH 010/237] Document rights --- src/types/utils/rights.rs | 74 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/types/utils/rights.rs b/src/types/utils/rights.rs index fecf268..dc4955a 100644 --- a/src/types/utils/rights.rs +++ b/src/types/utils/rights.rs @@ -1,56 +1,124 @@ use bitflags::bitflags; bitflags! { + /// Rights are instance-wide, per-user permissions for everything you may perform on the instance, + /// such as sending messages, editing messages, or shutting down the server. + /// They are separate from guild member permissions, which only apply to a given guild. + /// + /// # Notes + /// The default rights on Discord.com are 648540060672 ([source](https://github.com/spacebarchat/server/issues/878#issuecomment-1234669715)) + /// + /// # Reference + /// See pub struct Rights: u64 { + /// All rights const OPERATOR = 1 << 0; + /// Ability to alter or remove others' applications const MANAGE_APPLICATIONS = 1 << 1; + /// Same as the per-guild [MANAGE_GUILD] permission, but applies to all guilds and DM channels, can join any guild without invite const MANAGE_GUILDS = 1 << 2; + /// Can delete or edit any message they can read const MANAGE_MESSAGES = 1 << 3; + /// Can add, change, define rate limits of other users, + /// can also grant others [BYPASS_RATE_LIMITS] when combined + /// with [BYPASS_RATE_LIMITS] and [MANAGE_USERS]. const MANAGE_RATE_LIMITS = 1 << 4; + /// Can create, alter, enable and disable custom message routing rules in any channel/guild const MANAGE_ROUTING = 1 << 5; + /// Respond to or resolve other users' support tickets const MANAGE_TICKETS = 1 << 6; + /// Can create, alter, remove and ban users; can also create, modify and remove user groups const MANAGE_USERS = 1 << 7; + /// Can manually add members into their guilds and group DMs const ADD_MEMBERS = 1 << 8; + /// Makes the user exempt from all rate limits const BYPASS_RATE_LIMITS = 1 << 9; + /// Can create, edit and remove own applications const CREATE_APPLICATIONS = 1 << 10; + /// Can create guild channels and custom channels const CREATE_CHANNELS = 1 << 11; + /// Can create 1:1 DMs + /// + /// # Notes + /// A user without [SEND_MESSAGES] cannot be added to a DM const CREATE_DMS = 1 << 12; + /// Can create group DMs + /// + /// # Notes + /// A user without [SEND_MESSAGES] cannot be added to a DM const CREATE_DM_GROUPS = 1 << 13; + /// Can create guilds const CREATE_GUILDS = 1 << 14; + /// Can create mass invites in guilds where they have [CREATE_INSTANT_INVITE] const CREATE_INVITES = 1 << 15; + /// Can create roles and per-guild or per-channel permission + /// overrides in the guilds that they have permissions const CREATE_ROLES = 1 << 16; + /// Can create templates for guilds, custom channels and channels with custom routing const CREATE_TEMPLATES = 1 << 17; + /// Can create webhooks in the guilds that they have permissions const CREATE_WEBHOOKS = 1 << 18; + /// Can join guilds by using invites or vanity names const JOIN_GUILDS = 1 << 19; + /// Can modify the pinned messages in the guilds that they have permission const PIN_MESSAGES = 1 << 20; + /// Can react to messages, subject to permissions const SELF_ADD_REACTIONS = 1 << 21; + /// Can delete own messages const SELF_DELETE_MESSAGES = 1 << 22; + /// Can edit own messages const SELF_EDIT_MESSAGES = 1 << 23; + /// Can edit own username, nickname and avatar const SELF_EDIT_NAME = 1 << 24; + /// Can send messages in the channels that they have permissions const SEND_MESSAGES = 1 << 25; + /// Can use voice activities, such as watch together or whiteboard const USE_ACTIVITIES = 1 << 26; + /// Can use video and screenshare in guilds/channels that they have permissions const USE_VIDEO = 1 << 27; + /// Can use voice in guilds/channels that they have permissions const USE_VOICE = 1 << 28; + /// Can create user-specific invites in guilds that they have INVITE_USERS const INVITE_USERS = 1 << 29; + /// Can delete/disable own account const SELF_DELETE_DISABLE = 1 << 30; + /// Can use pay-to-use features once paid const DEBTABLE = 1 << 31; + /// Can earn money using monetization features in guilds that have MONETIZATION_ENABLED const CREDITABLE = 1 << 32; + /// Can kick or ban guild or group DM members in the guilds/groups where they have KICK_MEMBERS or BAN_MEMBERS const KICK_BAN_MEMBERS = 1 << 33; + /// Can leave the guilds or group DMs that they joined on their own (one can always leave a guild or group DMs where they have been force-added) const SELF_LEAVE_GROUPS = 1 << 34; + /// Inverts the presence confidentiality default (OPERATOR's presence is not routed by default, others' are) for a given user const PRESENCE = 1 << 35; + /// Can mark discoverable guilds where they have permissions to mark as discoverable const SELF_ADD_DISCOVERABLE = 1 << 36; + /// Can change anything in the primary guild directory const MANAGE_GUILD_DIRECTORY = 1 << 37; + /// Can send confetti, screenshake and use the random user mention (@someone) const POGGERS = 1 << 38; + /// Can use achievements and cheers const USE_ACHIEVEMENTS = 1 << 39; + /// Can initiate interactions const INITIATE_INTERACTIONS = 1 << 40; + /// Can respond to interactions const RESPOND_TO_INTERACTIONS = 1 << 41; + /// Can send backdated events const SEND_BACKDATED_EVENTS = 1 << 42; + /// Can accept mass (guild) invites const USE_MASS_INVITES = 1 << 43; + /// Can accept user-specific invites and DM requests const ACCEPT_INVITES = 1 << 44; + /// Can modify own flags const SELF_EDIT_FLAGS = 1 << 45; + /// Can modify other's flags const EDIT_FLAGS = 1 << 46; + /// Can manage other's groups const MANAGE_GROUPS = 1 << 47; + /// Can view server stats at /api/policies/stats const VIEW_SERVER_STATS = 1 << 48; + /// Can resend verification emails using /auth/verify/resend const RESEND_VERIFICATION_EMAIL = 1 << 49; } } @@ -60,10 +128,16 @@ impl Rights { (check_operator && self.contains(Rights::OPERATOR)) || self.contains(permission) } + /// Returns whether or not the Rights object has specific rights pub fn has(&self, permission: Rights, check_operator: bool) -> bool { (check_operator && self.contains(Rights::OPERATOR)) || self.contains(permission) } + /// Returns whether or not the Rights object has specific rights. + /// + /// # Notes + /// Unlike has, this returns an Error if we are missing rights + /// and Ok(true) otherwise pub fn has_throw(&self, permission: Rights) -> Result { if self.has(permission, true) { Ok(true) From ede965411e6755b953f619a9a9a5bcfd9611503d Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 11:26:00 +0200 Subject: [PATCH 011/237] Minor doc changes --- src/lib.rs | 1 + src/types/schema/user.rs | 3 +++ src/types/utils/jwt.rs | 6 ++++-- src/types/utils/snowflake.rs | 2 ++ src/voice.rs | 3 ++- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8315a4d..6563bed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ pub struct UrlBundle { } impl UrlBundle { + /// Creates a new UrlBundle from the relevant urls. pub fn new(api: String, wss: String, cdn: String) -> Self { Self { api: UrlBundle::parse_url(api), diff --git a/src/types/schema/user.rs b/src/types/schema/user.rs index c8cf5bb..9946e73 100644 --- a/src/types/schema/user.rs +++ b/src/types/schema/user.rs @@ -6,6 +6,7 @@ use crate::types::Snowflake; #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] +/// A schema used to modify a user. pub struct UserModifySchema { pub username: Option, pub avatar: Option, @@ -19,6 +20,8 @@ pub struct UserModifySchema { pub discriminator: Option, } +/// A schema used to create a private channel. +/// /// # Attributes: /// - recipients: The users to include in the private channel /// - access_tokens: The access tokens of users that have granted your app the `gdm.join` scope. Only usable for OAuth2 requests (which can only create group DMs). diff --git a/src/types/utils/jwt.rs b/src/types/utils/jwt.rs index c9f1aa5..951c58a 100644 --- a/src/types/utils/jwt.rs +++ b/src/types/utils/jwt.rs @@ -1,8 +1,8 @@ +#[allow(missing_docs)] +use crate::types::utils::Snowflake; use jsonwebtoken::{encode, EncodingKey, Header}; use serde::{Deserialize, Serialize}; -use crate::types::utils::Snowflake; - pub fn generate_token(id: &Snowflake, email: String, jwt_key: &str) -> String { let claims = Claims::new(&email, id); @@ -11,7 +11,9 @@ pub fn generate_token(id: &Snowflake, email: String, jwt_key: &str) -> String { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Claims { + /// When the token expires, unix epoch pub exp: i64, + /// When the token was issued pub iat: i64, pub email: String, pub id: String, diff --git a/src/types/utils/snowflake.rs b/src/types/utils/snowflake.rs index 81f3b5b..b34701a 100644 --- a/src/types/utils/snowflake.rs +++ b/src/types/utils/snowflake.rs @@ -18,6 +18,7 @@ const EPOCH: i64 = 1420070400000; pub struct Snowflake(u64); impl Snowflake { + /// Generates a snowflake for the current epoch. pub fn generate() -> Self { const WORKER_ID: u64 = 0; const PROCESS_ID: u64 = 1; @@ -31,6 +32,7 @@ impl Snowflake { Self(time as u64 | worker | process | increment) } + /// Returns the snowflake's timestamp pub fn timestamp(self) -> DateTime { Utc.timestamp_millis_opt((self.0 >> 22) as i64 + EPOCH) .unwrap() diff --git a/src/voice.rs b/src/voice.rs index 8b13789..c2fcaf2 100644 --- a/src/voice.rs +++ b/src/voice.rs @@ -1 +1,2 @@ - +//! Where the voice chat implementation will be, once it's finished. +//! For development on voice, see the feature/voice branch. From b632958b0f65948a17d195d656b948a983a0c64e Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 11:26:10 +0200 Subject: [PATCH 012/237] Document some flags --- src/types/entities/application.rs | 31 ++++++++++++++++++ src/types/entities/role.rs | 54 +++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/types/entities/application.rs b/src/types/entities/application.rs index 15e259c..d4805e9 100644 --- a/src/types/entities/application.rs +++ b/src/types/entities/application.rs @@ -8,6 +8,8 @@ use crate::types::{Team, User}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +/// # Reference +/// See pub struct Application { pub id: Snowflake, pub name: String, @@ -93,6 +95,8 @@ impl Application { } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +/// # Reference +/// See pub struct InstallParams { pub scopes: Vec, pub permissions: String, @@ -100,21 +104,37 @@ pub struct InstallParams { bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] + /// # Reference + /// See pub struct ApplicationFlags: u64 { + /// Indicates if an app uses the Auto Moderation API const APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 1 << 6; + /// Intent required for bots in 100 or more servers to receive presence_update events const GATEWAY_PRESENCE = 1 << 12; + /// Intent required for bots in under 100 servers to receive presence_update events, found on the Bot page in your app's settings on discord.com const GATEWAY_PRESENCE_LIMITED = 1 << 13; + /// Intent required for bots in 100 or more servers to receive member-related events like guild_member_add. + /// See the list of member-related events under GUILD_MEMBERS const GATEWAY_GUILD_MEMBERS = 1 << 14; + /// Intent required for bots in under 100 servers to receive member-related events like guild_member_add, found on the Bot page in your app's settings on discord.com. + /// See the list of member-related events under GUILD_MEMBERS const GATEWAY_GUILD_MEMBERS_LIMITED = 1 << 15; + /// Indicates unusual growth of an app that prevents verification const VERIFICATION_PENDING_GUILD_LIMIT = 1 << 16; + /// Indicates if an app is embedded within the Discord client (currently unavailable publicly) const EMBEDDED = 1 << 17; + /// Intent required for bots in 100 or more servers to receive message content const GATEWAY_MESSAGE_CONTENT = 1 << 18; + /// Intent required for bots in under 100 servers to receive message content, found on the Bot page in your app's settings on discord.com const GATEWAY_MESSAGE_CONTENT_LIMITED = 1 << 19; + /// Indicates if an app has registered slash commands const APPLICATION_COMMAND_BADGE = 1 << 23; } } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +/// # Reference +/// See pub struct ApplicationCommand { pub id: Snowflake, pub application_id: Snowflake, @@ -124,6 +144,8 @@ pub struct ApplicationCommand { } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +/// Reference +/// See pub struct ApplicationCommandOption { pub r#type: ApplicationCommandOptionType, pub name: String, @@ -142,15 +164,24 @@ pub struct ApplicationCommandOptionChoice { #[derive(Debug, Clone, Copy, PartialEq, Serialize_repr, Deserialize_repr)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[repr(i32)] +/// # Reference +/// See pub enum ApplicationCommandOptionType { SubCommand = 1, SubCommandGroup = 2, String = 3, + /// Any integer between -2^53 and 2^53 Integer = 4, Boolean = 5, User = 6, + /// Includes all channel types + categories Channel = 7, Role = 8, + /// Includes users and roles + Mentionable = 9, + /// Any double between -2^53 and 2^53 + Number = 10, + Attachment = 11, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index ef93b5d..0748453 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -54,56 +54,109 @@ pub struct RoleTags { bitflags! { #[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] + /// Permissions limit what users of certain roles can do on a Guild to Guild basis. + /// + /// # Reference: + /// See pub struct PermissionFlags: u64 { + /// Allows creation of instant invites const CREATE_INSTANT_INVITE = 1 << 0; + /// Allows kicking members const KICK_MEMBERS = 1 << 1; + /// Allows banning members const BAN_MEMBERS = 1 << 2; + /// Allows all permissions and bypasses channel permission overwrites const ADMINISTRATOR = 1 << 3; + /// Allows management and editing of channels const MANAGE_CHANNELS = 1 << 4; + /// Allows management and editing of the guild and guild settings const MANAGE_GUILD = 1 << 5; + /// Allows for the addition of reactions to messages const ADD_REACTIONS = 1 << 6; + /// Allows viewing of the audit log const VIEW_AUDIT_LOG = 1 << 7; + /// Allows using priority speaker in a voice channel const PRIORITY_SPEAKER = 1 << 8; + /// Allows the user to go live and share their screen const STREAM = 1 << 9; + /// Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels const VIEW_CHANNEL = 1 << 10; + /// Allows sending messages in a channel and creating threads in a forum (does not allow sending messages in threads) const SEND_MESSAGES = 1 << 11; + /// Allows sending /tts messages const SEND_TTS_MESSAGES = 1 << 12; + /// Allows deletion of other users' messages const MANAGE_MESSAGES = 1 << 13; + /// Links sent by users with this permission will be auto-embedded const EMBED_LINKS = 1 << 14; + /// Allows uploading images and files const ATTACH_FILES = 1 << 15; + /// Allows reading of message history const READ_MESSAGE_HISTORY = 1 << 16; + /// Allows using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel const MENTION_EVERYONE = 1 << 17; + /// Allows the usage of custom emojis from other servers const USE_EXTERNAL_EMOJIS = 1 << 18; + /// Allows viewing guild insights const VIEW_GUILD_INSIGHTS = 1 << 19; + /// Allows joining of a voice channel const CONNECT = 1 << 20; + /// Allows speaking in a voice channel const SPEAK = 1 << 21; + /// Allows muting members in a voice channel const MUTE_MEMBERS = 1 << 22; + /// Allows deafening of members in a voice channel const DEAFEN_MEMBERS = 1 << 23; + /// Allows moving of members between voice channels const MOVE_MEMBERS = 1 << 24; + /// Allows using voice activity (VAD = voice-activity-detection) in a voice channel const USE_VAD = 1 << 25; + /// Allows modification of own nickname const CHANGE_NICKNAME = 1 << 26; + /// Allows modification of other users' nicknames const MANAGE_NICKNAMES = 1 << 27; + /// Allows management and editing of roles const MANAGE_ROLES = 1 << 28; + /// Allows management and editing of webhooks const MANAGE_WEBHOOKS = 1 << 29; + /// Allows management and editing of emojis, stickers, and soundboard sounds const MANAGE_GUILD_EXPRESSIONS = 1 << 30; + /// Allows members to use application commands, including slash commands and context menu commands. const USE_APPLICATION_COMMANDS = 1 << 31; + /// Allows requesting to speak in stage channels. (*This permission is under active development and may be changed or removed.*) const REQUEST_TO_SPEAK = 1 << 32; + /// Allows creating, editing, and deleting scheduled events const MANAGE_EVENTS = 1 << 33; + /// Allows deleting and archiving threads, and viewing all private threads const MANAGE_THREADS = 1 << 34; + /// Allows creating public and announcement threads const CREATE_PUBLIC_THREADS = 1 << 35; + /// Allows creating private threads const CREATE_PRIVATE_THREADS = 1 << 36; + /// Allows the usage of custom stickers from other servers const USE_EXTERNAL_STICKERS = 1 << 37; + /// Allows sending messages in threads const SEND_MESSAGES_IN_THREADS = 1 << 38; + /// Allows using Activities in a voice channel const USE_EMBEDDED_ACTIVITIES = 1 << 39; + /// Allows timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels const MODERATE_MEMBERS = 1 << 40; + /// Allows viewing role subscription insights const VIEW_CREATOR_MONETIZATION_ANALYTICS = 1 << 41; + /// Allows using the soundboard in a voice channel const USE_SOUNDBOARD = 1 << 42; + /// Allows using custom soundboard sounds from other servers const USE_EXTERNAL_SOUNDS = 1 << 45; + /// Allows sending voice messages const SEND_VOICE_MESSAGES = 1 << 46; } } impl PermissionFlags { + /// Returns if the PermissionFlags object has specific permissions + /// + /// # Notes + /// Note that if the object has the [PermissionFlags::ADMINISTRATOR] permission, this always returns true pub fn has_permission(&self, permission: PermissionFlags) -> bool { self.contains(permission) || self.contains(PermissionFlags::ADMINISTRATOR) } @@ -114,6 +167,7 @@ impl PermissionFlags { } /// Creates a String of Permissions from a given [`Vec`] of [`PermissionFlags`]. + /// /// # Example: /// ``` /// use chorus::types::{PermissionFlags}; From e6dc44754ca8a77d484feedf0763c39d8c7511e8 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 11:45:25 +0200 Subject: [PATCH 013/237] Forgot this since had the lint on my local copy --- src/types/utils/jwt.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/types/utils/jwt.rs b/src/types/utils/jwt.rs index 951c58a..ca0aebb 100644 --- a/src/types/utils/jwt.rs +++ b/src/types/utils/jwt.rs @@ -1,4 +1,3 @@ -#[allow(missing_docs)] use crate::types::utils::Snowflake; use jsonwebtoken::{encode, EncodingKey, Header}; use serde::{Deserialize, Serialize}; From 552032a61e60a18c8caee7767b1b43fb4e6a2b71 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 16:04:08 +0000 Subject: [PATCH 014/237] Capitalise docs Co-authored-by: SpecificProtagonist --- src/types/events/presence.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/events/presence.rs b/src/types/events/presence.rs index 0aef27e..c2d985e 100644 --- a/src/types/events/presence.rs +++ b/src/types/events/presence.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; /// Sent by the client to update its status and presence; /// See pub struct UpdatePresence { - /// unix time of when the client went idle, or none if client is not idle + /// Unix time of when the client went idle, or none if client is not idle. pub since: Option, /// the client's status (online, invisible, offline, dnd, idle..) pub status: UserStatus, From b172e5910dce3ff303064876ebb8026957ee8e51 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 16:04:49 +0000 Subject: [PATCH 015/237] Update src/types/utils/rights.rs Co-authored-by: SpecificProtagonist --- src/types/utils/rights.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/utils/rights.rs b/src/types/utils/rights.rs index dc4955a..52d68cd 100644 --- a/src/types/utils/rights.rs +++ b/src/types/utils/rights.rs @@ -78,7 +78,7 @@ bitflags! { const USE_VIDEO = 1 << 27; /// Can use voice in guilds/channels that they have permissions const USE_VOICE = 1 << 28; - /// Can create user-specific invites in guilds that they have INVITE_USERS + /// Can create user-specific invites in guilds that they have the [`INVITE_USERS`] right in. const INVITE_USERS = 1 << 29; /// Can delete/disable own account const SELF_DELETE_DISABLE = 1 << 30; From 84ada8b94a73b13a204bb918d0cca588d89f2491 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 16:05:27 +0000 Subject: [PATCH 016/237] Update src/types/utils/rights.rs Co-authored-by: SpecificProtagonist --- src/types/utils/rights.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/utils/rights.rs b/src/types/utils/rights.rs index 52d68cd..666cf17 100644 --- a/src/types/utils/rights.rs +++ b/src/types/utils/rights.rs @@ -84,7 +84,7 @@ bitflags! { const SELF_DELETE_DISABLE = 1 << 30; /// Can use pay-to-use features once paid const DEBTABLE = 1 << 31; - /// Can earn money using monetization features in guilds that have MONETIZATION_ENABLED + /// Can earn money using monetization features in guilds that have [`MonetizationEnabled`](crate::types::types::guild_configuration::GuildFeatures::MonetizationEnabled) const CREDITABLE = 1 << 32; /// Can kick or ban guild or group DM members in the guilds/groups where they have KICK_MEMBERS or BAN_MEMBERS const KICK_BAN_MEMBERS = 1 << 33; From e64233e6d81a75ccceb39d5ccec076c69b6ccafb Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 16:06:35 +0000 Subject: [PATCH 017/237] Update src/types/utils/rights.rs Co-authored-by: SpecificProtagonist --- src/types/utils/rights.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/utils/rights.rs b/src/types/utils/rights.rs index 666cf17..bab08db 100644 --- a/src/types/utils/rights.rs +++ b/src/types/utils/rights.rs @@ -86,7 +86,7 @@ bitflags! { const DEBTABLE = 1 << 31; /// Can earn money using monetization features in guilds that have [`MonetizationEnabled`](crate::types::types::guild_configuration::GuildFeatures::MonetizationEnabled) const CREDITABLE = 1 << 32; - /// Can kick or ban guild or group DM members in the guilds/groups where they have KICK_MEMBERS or BAN_MEMBERS + /// Can kick or ban guild or group DM members in the guilds/groups where they have [`KICK_MEMBERS`](crate::types::PermissionFlags::KICK_MEMBERS) or [`BAN_MEMBERS`](crate::types::PermissionFlags::BAN_MEMBERS) const KICK_BAN_MEMBERS = 1 << 33; /// Can leave the guilds or group DMs that they joined on their own (one can always leave a guild or group DMs where they have been force-added) const SELF_LEAVE_GROUPS = 1 << 34; From 0f300cfb2034f4c07e628ab27248c8fb07b3e151 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 16:06:49 +0000 Subject: [PATCH 018/237] Update src/types/utils/snowflake.rs Co-authored-by: SpecificProtagonist --- src/types/utils/snowflake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/utils/snowflake.rs b/src/types/utils/snowflake.rs index b34701a..9796084 100644 --- a/src/types/utils/snowflake.rs +++ b/src/types/utils/snowflake.rs @@ -18,7 +18,7 @@ const EPOCH: i64 = 1420070400000; pub struct Snowflake(u64); impl Snowflake { - /// Generates a snowflake for the current epoch. + /// Generates a snowflake for the current timestamp, with worker id 0 and process id 1. pub fn generate() -> Self { const WORKER_ID: u64 = 0; const PROCESS_ID: u64 = 1; From 76370517332c11827f153c73ac2e8544dad31d97 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 16:07:06 +0000 Subject: [PATCH 019/237] Update src/types/utils/rights.rs Co-authored-by: SpecificProtagonist --- src/types/utils/rights.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/utils/rights.rs b/src/types/utils/rights.rs index bab08db..5a3c373 100644 --- a/src/types/utils/rights.rs +++ b/src/types/utils/rights.rs @@ -90,7 +90,7 @@ bitflags! { const KICK_BAN_MEMBERS = 1 << 33; /// Can leave the guilds or group DMs that they joined on their own (one can always leave a guild or group DMs where they have been force-added) const SELF_LEAVE_GROUPS = 1 << 34; - /// Inverts the presence confidentiality default (OPERATOR's presence is not routed by default, others' are) for a given user + /// Inverts the presence confidentiality default ([`OPERATOR`]'s presence is not routed by default, others' are) for a given user const PRESENCE = 1 << 35; /// Can mark discoverable guilds where they have permissions to mark as discoverable const SELF_ADD_DISCOVERABLE = 1 << 36; From 590afc8c9ddbd4aeef6855f320ba2d813db0753d Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 18:12:38 +0200 Subject: [PATCH 020/237] Permissions with code blocks --- src/api/channels/reactions.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index 467af56..cdf65ce 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -63,7 +63,7 @@ impl ReactionMeta { /// Deletes all the reactions for a given emoji on a message. /// - /// This endpoint requires the MANAGE_MESSAGES permission. + /// This endpoint requires the `MANAGE_MESSAGES` permission. /// /// The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. /// To use custom emoji, the format of the emoji string must be name:id. @@ -89,13 +89,13 @@ impl ReactionMeta { /// Create a reaction on a message. /// - /// This endpoint requires the READ_MESSAGE_HISTORY permission. + /// This endpoint requires the `READ_MESSAGE_HISTORY` permission. /// /// Additionally, if nobody else has reacted to the message using this emoji, - /// this endpoint requires the ADD_REACTIONS permission. + /// this endpoint requires the `ADD_REACTIONS` permission. /// /// The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. - /// To use custom emoji, the format of the emoji string must be name:id. + /// To use custom emoji, the format of the emoji string must be `name:id`. /// /// # Reference /// See @@ -140,12 +140,12 @@ impl ReactionMeta { /// Deletes a user's reaction to a message. /// - /// This endpoint requires the MANAGE_MESSAGES permission. + /// This endpoint requires the `MANAGE_MESSAGES` permission. /// /// The reaction emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. /// To use custom emoji, the format of the emoji string must be name:id. /// - /// Fires a Message Reaction Remove Gateway event. + /// Fires a `Message Reaction Remove` Gateway event. /// /// # Reference /// See From d50e969a074d505cb260b6895466a3ad3345d3a4 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 29 Jul 2023 18:12:49 +0200 Subject: [PATCH 021/237] Document a small bit of attachment --- src/types/entities/attachment.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/types/entities/attachment.rs b/src/types/entities/attachment.rs index 4261203..75ec860 100644 --- a/src/types/entities/attachment.rs +++ b/src/types/entities/attachment.rs @@ -4,9 +4,12 @@ use crate::types::utils::Snowflake; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +/// # Reference +/// See pub struct Attachment { pub id: Snowflake, pub filename: String, + /// Max 1024 characters pub description: Option, pub content_type: Option, pub size: u64, @@ -15,7 +18,13 @@ pub struct Attachment { pub height: Option, pub width: Option, pub ephemeral: Option, + /// The duration of the audio file (only for voice messages) pub duration_secs: Option, + /// A Base64 encoded bytearray representing a sampled waveform (only for voice messages) + /// + /// # Notes + /// Note that this is computed on the client side. + /// This means it can be spoofed and isn't necessarily accurate. pub waveform: Option, #[serde(skip_serializing)] #[cfg_attr(feature = "sqlx", sqlx(default))] @@ -26,6 +35,7 @@ pub struct Attachment { pub struct PartialDiscordFileAttachment { pub id: Option, pub filename: String, + /// Max 1024 characters pub description: Option, pub content_type: Option, pub size: Option, @@ -34,7 +44,13 @@ pub struct PartialDiscordFileAttachment { pub height: Option, pub width: Option, pub ephemeral: Option, + /// The duration of the audio file (only for voice messages) pub duration_secs: Option, + /// A Base64 encoded bytearray representing a sampled waveform (only for voice messages) + /// + /// # Notes + /// Note that this is computed on the client side. + /// This means it can be spoofed and isn't necessarily accurate. pub waveform: Option, #[serde(skip_serializing)] pub content: Vec, @@ -62,6 +78,7 @@ impl PartialDiscordFileAttachment { (content, updated_struct) } + /// Moves `self.filename` out of `self` and returns it. pub fn move_filename(self) -> (String, PartialDiscordFileAttachment) { let filename = self.filename; let updated_struct = PartialDiscordFileAttachment { @@ -83,6 +100,7 @@ impl PartialDiscordFileAttachment { (filename, updated_struct) } + /// Moves `self.content_type` out of `self` and returns it. pub fn move_content_type(self) -> (Option, PartialDiscordFileAttachment) { let content_type = self.content_type; let updated_struct = PartialDiscordFileAttachment { From b72ebf36ed9af0fa09b588346d3ad59cd3aedae7 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sun, 30 Jul 2023 08:26:26 +0200 Subject: [PATCH 022/237] Documemtaiom --- src/api/auth/login.rs | 1 + src/api/auth/register.rs | 1 + src/api/channels/channels.rs | 20 ++++++++++++++++++-- src/api/channels/messages.rs | 9 ++++++++- src/api/channels/permissions.rs | 6 ++++++ src/api/users/users.rs | 19 +++++++++++++++++++ src/types/entities/channel.rs | 32 ++++++++++++++++++++++++++++++++ src/types/utils/snowflake.rs | 2 ++ 8 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 60ee52b..4cc58bb 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -13,6 +13,7 @@ use crate::types::{GatewayIdentifyPayload, LoginResult, LoginSchema}; impl Instance { /// Logs into an existing account on the spacebar server. + // TODO: Couldn't find reference pub async fn login_account(&mut self, login_schema: &LoginSchema) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/login"; let chorus_request = ChorusRequest { diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 630ad9d..ae41c47 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -15,6 +15,7 @@ use crate::{ impl Instance { /// Registers a new user on the server. + // TODO: Couldn't find reference pub async fn register_account( &mut self, register_schema: &RegisterSchema, diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index db94056..0f6d64a 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -12,6 +12,9 @@ use crate::{ impl Channel { /// Retrieves a channel from the server. + /// + /// # Reference + /// See pub async fn get(user: &mut UserMeta, channel_id: Snowflake) -> ChorusResult { let url = user.belongs_to.borrow().urls.api.clone(); let chorus_request = ChorusRequest { @@ -24,6 +27,9 @@ impl Channel { } /// Deletes self. + /// + /// # Reference + /// See pub async fn delete(self, user: &mut UserMeta) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() @@ -40,6 +46,9 @@ impl Channel { /// Modifies a channel with the provided data. /// Returns the new Channel. + /// + /// # Reference + /// See pub async fn modify( &self, modify_data: ChannelModifySchema, @@ -61,6 +70,9 @@ impl Channel { } /// Fetches recent messages from a channel. + /// + /// # Reference + /// See pub async fn messages( range: GetChannelMessagesSchema, channel_id: Snowflake, @@ -83,8 +95,10 @@ impl Channel { .await } + /// Adds a recipient to a group DM. + /// /// # Reference: - /// Read: + /// See pub async fn add_channel_recipient( &self, recipient_id: Snowflake, @@ -110,8 +124,10 @@ impl Channel { .await } + /// Removes a recipient from a group DM. + /// /// # Reference: - /// Read: + /// See pub async fn remove_channel_recipient( &self, recipient_id: Snowflake, diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 9c06f6f..5f1745b 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -12,6 +12,9 @@ use crate::types::{Message, MessageSendSchema, Snowflake}; impl Message { /// Sends a message in the channel with the provided channel_id. /// Returns the sent message. + /// + /// # Reference + /// See pub async fn send( user: &mut UserMeta, channel_id: Snowflake, @@ -71,8 +74,12 @@ impl Message { impl UserMeta { /// Sends a message in the channel with the provided channel_id. /// Returns the sent message. + /// /// # Notes - /// Shorthand call for Message::send() + /// Shorthand call for [`Message::send`] + /// + /// # Reference + /// See pub async fn send_message( &mut self, message: MessageSendSchema, diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 57feb5d..d68034e 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -11,6 +11,9 @@ use crate::{ impl types::Channel { /// Edits the permission overwrites for a channel. + /// + /// # Reference + /// See pub async fn edit_permissions( user: &mut UserMeta, channel_id: Snowflake, @@ -38,6 +41,9 @@ impl types::Channel { } /// Deletes a permission overwrite for a channel. + /// + /// # Reference + /// See pub async fn delete_permission( user: &mut UserMeta, channel_id: Snowflake, diff --git a/src/api/users/users.rs b/src/api/users/users.rs index f673ee3..16c2560 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -16,6 +16,10 @@ impl UserMeta { /// /// # Notes /// This function is a wrapper around [`User::get`]. + /// + /// # Reference + /// See and + /// pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { User::get(user, id).await } @@ -33,6 +37,9 @@ impl UserMeta { } /// Modifies the current user's representation. (See [`User`]) + /// + /// # Reference + /// See pub async fn modify(&mut self, modify_schema: UserModifySchema) -> ChorusResult { if modify_schema.new_password.is_some() || modify_schema.email.is_some() @@ -57,6 +64,9 @@ impl UserMeta { } /// Deletes the user from the Instance. + /// + /// # Reference + /// See pub async fn delete(mut self) -> ChorusResult<()> { let request = Client::new() .post(format!( @@ -74,6 +84,10 @@ impl UserMeta { impl User { /// Gets a user by id, or if the id is None, gets the current user. + /// + /// # Reference + /// See and + /// pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { let url_api = user.belongs_to.borrow().urls.api.clone(); let url = if id.is_none() { @@ -96,6 +110,7 @@ impl User { } /// Gets the user's settings. + // TODO: Couldn't find reference pub async fn get_settings( token: &String, url_api: &String, @@ -127,6 +142,10 @@ impl Instance { /// /// # Notes /// This function is a wrapper around [`User::get`]. + /// + /// # Reference + /// See and + /// pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult { let mut user = UserMeta::shell(Rc::new(RefCell::new(self.clone())), token).await; let result = User::get(&mut user, id).await; diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 154b83c..98aa9ed 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -12,6 +12,10 @@ use crate::types::{ #[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +/// Represents a guild of private channel +/// +/// # Reference +/// See pub struct Channel { pub application_id: Option, #[cfg(feature = "sqlx")] @@ -120,27 +124,55 @@ pub struct DefaultReaction { #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[repr(i32)] +/// # Reference +/// See pub enum ChannelType { #[default] + /// A text channel within a guild GuildText = 0, + /// A private channel between two users Dm = 1, + /// A voice channel within a guild GuildVoice = 2, + /// A private channel between multiple users GroupDm = 3, + /// An organizational category that contains up to 50 channels GuildCategory = 4, + /// Similar to [GuildText], a channel that users can follow and crosspost into their own guild GuildNews = 5, + /// A channel in which game developers can sell their game on Discord + /// + /// # Note + /// Deprecated. GuildStore = 6, + // FIXME userdoccers says 7 is GuildLfg, is this a spacebar specific thing? Encrypted = 7, + // FIXME userdoccers says 8 is LfgGuildDm, is this a spacebar specific thing? EncryptedThreads = 8, + // FIXME userdoccers says 9 is ThreadAlpha, was this changed? Transactional = 9, + /// A thread within a [GuildNews] channel GuildNewsThread = 10, + /// A thread within a [GuildText], [GuildForum], or [GuildMedia] channel GuildPublicThread = 11, + /// A thread within a [GuildText] channel, that is only viewable by those invited and those with the [ManageThreads] permission GuildPrivateThread = 12, + /// A voice channel for hosting events with an audience in a guild GuildStageVoice = 13, + /// The main channel in a hub containing the listed guilds Directory = 14, + /// A channel that can only contain threads GuildForum = 15, + /// A channel that can only contain threads in a gallery view + GuildMedia = 16, + // TODO: Couldn't find reference TicketTracker = 33, + // TODO: Couldn't find reference Kanban = 34, + // TODO: Couldn't find reference VoicelessWhiteboard = 35, + // TODO: Couldn't find reference CustomStart = 64, + // TODO: Couldn't find reference Unhandled = 255, } diff --git a/src/types/utils/snowflake.rs b/src/types/utils/snowflake.rs index 9796084..a9f572b 100644 --- a/src/types/utils/snowflake.rs +++ b/src/types/utils/snowflake.rs @@ -11,6 +11,8 @@ use sqlx::Type; const EPOCH: i64 = 1420070400000; /// Unique identifier including a timestamp. +/// +/// # Reference /// See #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr(feature = "sqlx", derive(Type))] From ba25cab1e9af6a09ba8e11dadea3d748f9def50a Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sun, 30 Jul 2023 08:31:12 +0200 Subject: [PATCH 023/237] Fix broken links --- src/types/entities/channel.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 98aa9ed..43ca54b 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -138,7 +138,7 @@ pub enum ChannelType { GroupDm = 3, /// An organizational category that contains up to 50 channels GuildCategory = 4, - /// Similar to [GuildText], a channel that users can follow and crosspost into their own guild + /// Similar to [GuildText](ChannelType::GuildText), a channel that users can follow and crosspost into their own guild GuildNews = 5, /// A channel in which game developers can sell their game on Discord /// @@ -151,11 +151,11 @@ pub enum ChannelType { EncryptedThreads = 8, // FIXME userdoccers says 9 is ThreadAlpha, was this changed? Transactional = 9, - /// A thread within a [GuildNews] channel + /// A thread within a [GuildNews](ChannelType::GuildNews) channel GuildNewsThread = 10, - /// A thread within a [GuildText], [GuildForum], or [GuildMedia] channel + /// A thread within a [GuildText](ChannelType::GuildText), [GuildForum](ChannelType::GuildForum), or [GuildMedia](ChannelType::GuildMedia) channel GuildPublicThread = 11, - /// A thread within a [GuildText] channel, that is only viewable by those invited and those with the [ManageThreads] permission + /// A thread within a [GuildText](ChannelType::GuildText) channel, that is only viewable by those invited and those with the [MANAGE_THREADS](crate::types::entities::PermissionFlags::MANAGE_THREADS) permission GuildPrivateThread = 12, /// A voice channel for hosting events with an audience in a guild GuildStageVoice = 13, From 1ce9bf08cd2bcf91ff1c685512ec2a272f94c645 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sun, 30 Jul 2023 09:04:31 +0200 Subject: [PATCH 024/237] Guilds + Channels --- src/api/guilds/guilds.rs | 29 ++++++++++++++++++++++++++++- src/api/guilds/member.rs | 9 +++++++++ src/api/guilds/roles.rs | 20 ++++++++++++++------ src/types/entities/channel.rs | 14 ++++++++++++++ 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 9b9d87f..f598414 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -12,6 +12,9 @@ use crate::types::{Channel, ChannelCreateSchema, Guild, GuildCreateSchema}; impl Guild { /// Creates a new guild. + /// + /// # Reference + /// See pub async fn create( user: &mut UserMeta, guild_create_schema: GuildCreateSchema, @@ -41,6 +44,9 @@ impl Guild { /// Ok(_) => println!("Guild deleted successfully"), /// } /// ``` + /// + /// # Reference + /// See pub async fn delete(user: &mut UserMeta, guild_id: Snowflake) -> ChorusResult<()> { let url = format!( "{}/guilds/{}/delete/", @@ -57,6 +63,14 @@ impl Guild { } /// Creates a new channel in a guild. + /// + /// Requires the [MANAGE_CHANNELS](crate::types::PermissionFlags::MANAGE_CHANNELS) permission. + /// + /// # Notes + /// This method is a wrapper for [Channel::create]. + /// + /// # Reference + /// See pub async fn create_channel( &self, user: &mut UserMeta, @@ -65,7 +79,12 @@ impl Guild { Channel::create(user, self.id, schema).await } - /// Returns a list of the guild's channels + /// Returns a list of the guild's channels. + /// + /// Doesn't include threads. + /// + /// # Reference + /// See pub async fn channels(&self, user: &mut UserMeta) -> ChorusResult> { let chorus_request = ChorusRequest { request: Client::new() @@ -97,6 +116,9 @@ impl Guild { } /// Fetches a guild by its id. + /// + /// # Reference + /// See pub async fn get(guild_id: Snowflake, user: &mut UserMeta) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() @@ -115,6 +137,11 @@ impl Guild { impl Channel { /// Creates a new channel in a guild. + /// + /// Requires the [MANAGE_CHANNELS](crate::types::PermissionFlags::MANAGE_CHANNELS) permission. + /// + /// # Reference + /// See pub async fn create( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index 1cf1a08..06b5154 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -10,6 +10,9 @@ use crate::{ impl types::GuildMember { /// Retrieves a guild member. + /// + /// # Reference + /// See pub async fn get( user: &mut UserMeta, guild_id: Snowflake, @@ -31,6 +34,9 @@ impl types::GuildMember { } /// Adds a role to a guild member. + /// + /// # Reference + /// See pub async fn add_role( user: &mut UserMeta, guild_id: Snowflake, @@ -52,6 +58,9 @@ impl types::GuildMember { } /// Removes a role from a guild member. + /// + /// # Reference + /// See pub async fn remove_role( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 81aca03..e76749e 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -12,11 +12,12 @@ use crate::{ impl types::RoleObject { /// Retrieves a list of roles for a given guild. /// - /// Returns Ok(None) if the guild has no roles. + /// # Reference + /// See pub async fn get_all( user: &mut UserMeta, guild_id: Snowflake, - ) -> ChorusResult>> { + ) -> ChorusResult> { let url = format!( "{}/guilds/{}/roles/", user.belongs_to.borrow().urls.api, @@ -30,13 +31,11 @@ impl types::RoleObject { .deserialize_response::>(user) .await .unwrap(); - if roles.is_empty() { - return Ok(None); - } - Ok(Some(roles)) + Ok(roles) } /// Retrieves a single role for a given guild. + // TODO: Couldn't find reference pub async fn get( user: &mut UserMeta, guild_id: Snowflake, @@ -58,6 +57,9 @@ impl types::RoleObject { } /// Creates a new role for a given guild. + /// + /// # Reference + /// See pub async fn create( user: &mut UserMeta, guild_id: Snowflake, @@ -83,6 +85,9 @@ impl types::RoleObject { } /// Updates the position of a role in a given guild's hierarchy. + /// + /// # Reference + /// See pub async fn position_update( user: &mut UserMeta, guild_id: Snowflake, @@ -110,6 +115,9 @@ impl types::RoleObject { } /// Updates a role in a guild. + /// + /// # Reference + /// See pub async fn update( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 43ca54b..60304f9 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -72,9 +72,15 @@ pub struct Channel { } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +/// A tag that can be applied to a thread in a [ChannelType::GuildForum] or [ChannelType::GuildMedia] channel. +/// +/// # Reference +/// See pub struct Tag { pub id: Snowflake, + /// The name of the tag (max 20 characters) pub name: String, + /// Whether this tag can only be added to or removed from threads by members with the [MANAGE_THREADS](crate::types::PermissionFlags::MANAGE_THREADS) permission pub moderated: bool, pub emoji_id: Option, pub emoji_name: Option, @@ -95,6 +101,8 @@ pub struct PermissionOverwrite { } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +/// # Reference +/// See pub struct ThreadMetadata { pub archived: bool, pub auto_archive_duration: i32, @@ -105,6 +113,8 @@ pub struct ThreadMetadata { } #[derive(Default, Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +/// # Reference +/// See pub struct ThreadMember { pub id: Option, pub user_id: Option, @@ -114,6 +124,10 @@ pub struct ThreadMember { } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +/// Specifies the emoji to use as the default way to react to a [ChannelType::GuildForum] or [ChannelType::GuildMedia] channel post. +/// +/// # Reference +/// See pub struct DefaultReaction { #[serde(default)] pub emoji_id: Option, From 8b7693605005eaa9f3c9bd6aa41760b6883fdf60 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sun, 30 Jul 2023 09:10:32 +0200 Subject: [PATCH 025/237] Fix the test --- tests/roles.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/roles.rs b/tests/roles.rs index 1675367..f45fb62 100644 --- a/tests/roles.rs +++ b/tests/roles.rs @@ -24,7 +24,6 @@ async fn create_and_get_roles() { let expected = types::RoleObject::get_all(&mut bundle.user, guild) .await - .unwrap() .unwrap()[2] .clone(); From 50538eb15d6e43b566b82f2721390a864529514c Mon Sep 17 00:00:00 2001 From: Vivien Date: Sun, 30 Jul 2023 20:23:12 +0200 Subject: [PATCH 026/237] change signed to unsigned integer --- src/types/entities/message.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 745d001..be0e060 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -178,9 +178,11 @@ pub struct EmbedField { #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct Reaction { - pub count: i32, + pub count: u32, + pub burst_count: u32, pub me: bool, pub emoji: Emoji, + } #[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] From 92bc958cf1e7613d19114fd5c9137b88c68c6391 Mon Sep 17 00:00:00 2001 From: Vivien Date: Sun, 30 Jul 2023 20:27:13 +0200 Subject: [PATCH 027/237] update of reaction struct --- src/types/entities/message.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index be0e060..4327ec3 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -1,3 +1,5 @@ + + use serde::{Deserialize, Serialize}; use crate::types::{ @@ -181,6 +183,8 @@ pub struct Reaction { pub count: u32, pub burst_count: u32, pub me: bool, + pub burst_me: bool, + pub burst_colors: Vec, pub emoji: Emoji, } From 2249ae65d74089c4e19b2e4e3d545cd70bf93f60 Mon Sep 17 00:00:00 2001 From: Flori <39242991+bitfl0wer@users.noreply.github.com> Date: Sun, 30 Jul 2023 20:35:02 +0200 Subject: [PATCH 028/237] Remove newline --- src/types/entities/message.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 4327ec3..41d24b6 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -186,7 +186,6 @@ pub struct Reaction { pub burst_me: bool, pub burst_colors: Vec, pub emoji: Emoji, - } #[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] From 60393a5686894221682cb0c9a85e7deef8bfc7b3 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:01:25 +0200 Subject: [PATCH 029/237] Docs --- src/api/channels/channels.rs | 17 +++++++++++++++++ src/api/channels/permissions.rs | 14 ++++++++++++-- src/api/channels/reactions.rs | 18 +++++------------- src/api/guilds/guilds.rs | 4 +++- src/api/guilds/member.rs | 4 ++++ src/api/guilds/roles.rs | 6 ++++++ src/api/invites/mod.rs | 12 +++++------- src/api/policies/instance/instance.rs | 6 ++++++ src/api/users/channels.rs | 5 ++++- src/api/users/guilds.rs | 6 ++++-- src/ratelimiter.rs | 7 +++++++ src/types/entities/emoji.rs | 2 ++ src/types/entities/guild_member.rs | 4 ++++ src/types/entities/message.rs | 10 ++++++++-- src/types/entities/sticker.rs | 10 ++++++++++ 15 files changed, 97 insertions(+), 28 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 0f6d64a..ba99a8f 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -28,6 +28,9 @@ impl Channel { /// Deletes self. /// + /// Requires the [`MANAGE_CHANNEL`](crate::types::PermissionFlags::MANAGE_CHANNEL) permission in a guild, or + /// the [`MANAGE_THREADS`](crate::types::PermissionFlags::MANAGE_THREADS) permission if the channel is a thread. + /// /// # Reference /// See pub async fn delete(self, user: &mut UserMeta) -> ChorusResult<()> { @@ -47,6 +50,15 @@ impl Channel { /// Modifies a channel with the provided data. /// Returns the new Channel. /// + /// Requires the [`MANAGE_CHANNEL`](crate::types::PermissionFlags::MANAGE_CHANNEL) permission in a guild. + /// + /// If modifying permission overwrites, the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission is required. + /// Only permissions you have in the guild or parent channel (if applicable) can be allowed/denied + /// (unless you have a [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) overwrite in the channel). + /// + /// If modifying a thread and setting `archived` to `false`, when `locked` is also `false`, only the [`SEND_MESSAGES`](crate::types::PermissionFlags::SEND_MESSAGES) permission is required. + /// Otherwise, requires the [`MANAGE_THREADS`](crate::types::PermissionFlags::MANAGE_THREADS) permission. Requires the thread to have `archived` set to `false` or be set to `false` in the request. + /// /// # Reference /// See pub async fn modify( @@ -71,6 +83,11 @@ impl Channel { /// Fetches recent messages from a channel. /// + /// If operating on a guild channel, this endpoint requires the [`VIEW_CHANNEL`](crate::types::PermissionFlags::VIEW_CHANNEL) permission. + /// + /// If the user is missing the [`READ_MESSAGE_HISTORY`](crate::types::PermissionFlags::READ_MESSAGE_HISTORY) permission, + /// this method returns an empty list. + /// /// # Reference /// See pub async fn messages( diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index d68034e..7c83d85 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -10,7 +10,13 @@ use crate::{ }; impl types::Channel { - /// Edits the permission overwrites for a channel. + /// Edits the permission overwrites for a user or role in a channel. + /// + /// Only usable for guild channels. + /// + /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. + /// Only permissions you have in the guild or parent channel (if applicable) can be allowed/denied + /// (unless you have a [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) overwrite in the channel). /// /// # Reference /// See @@ -40,7 +46,11 @@ impl types::Channel { chorus_request.handle_request_as_result(user).await } - /// Deletes a permission overwrite for a channel. + /// Deletes a permission overwrite for a user or role in a channel. + /// + /// Only usable for guild channels. + /// + /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. /// /// # Reference /// See diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index cdf65ce..b7b221f 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -17,9 +17,7 @@ pub struct ReactionMeta { impl ReactionMeta { /// Deletes all reactions for a message. /// - /// This endpoint requires the `MANAGE_MESSAGES` permission to be present on the current user. - /// - /// Fires a `Message Reaction Remove All` Gateway event. + /// This endpoint requires the [`MANAGE_MESSAGES`](crate::types::PermissionFlags::MANAGE_MESSAGES) permission. /// /// # Reference /// See @@ -63,13 +61,11 @@ impl ReactionMeta { /// Deletes all the reactions for a given emoji on a message. /// - /// This endpoint requires the `MANAGE_MESSAGES` permission. + /// This endpoint requires the [`MANAGE_MESSAGES`](crate::types::PermissionFlags::MANAGE_MESSAGES) permission. /// /// The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. /// To use custom emoji, the format of the emoji string must be name:id. /// - /// Fires the `Message Reaction Remove Emoji` Gateway event. - /// /// # Reference /// See pub async fn delete_emoji(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { @@ -89,10 +85,10 @@ impl ReactionMeta { /// Create a reaction on a message. /// - /// This endpoint requires the `READ_MESSAGE_HISTORY` permission. + /// This endpoint requires the [`READ_MESSAGE_HISTORY`](crate::types::PermissionFlags::READ_MESSAGE_HISTORY) permission. /// /// Additionally, if nobody else has reacted to the message using this emoji, - /// this endpoint requires the `ADD_REACTIONS` permission. + /// this endpoint requires the [`ADD_REACTIONS`](crate::types::PermissionFlags::ADD_REACTIONS) permission. /// /// The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. /// To use custom emoji, the format of the emoji string must be `name:id`. @@ -119,8 +115,6 @@ impl ReactionMeta { /// The reaction emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. /// To use custom emoji, the format of the emoji string must be name:id. /// - /// Fires a `Message Reaction Remove` Gateway event. - /// /// # Reference /// See pub async fn remove(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { @@ -140,13 +134,11 @@ impl ReactionMeta { /// Deletes a user's reaction to a message. /// - /// This endpoint requires the `MANAGE_MESSAGES` permission. + /// This endpoint requires the [`MANAGE_MESSAGES`](crate::types::PermissionFlags::MANAGE_MESSAGES) permission. /// /// The reaction emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. /// To use custom emoji, the format of the emoji string must be name:id. /// - /// Fires a `Message Reaction Remove` Gateway event. - /// /// # Reference /// See pub async fn delete_user( diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index f598414..43a8cdf 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -32,6 +32,8 @@ impl Guild { /// Deletes a guild by its id. /// + /// User must be the owner. + /// /// # Example /// /// ```rs @@ -118,7 +120,7 @@ impl Guild { /// Fetches a guild by its id. /// /// # Reference - /// See + /// See pub async fn get(guild_id: Snowflake, user: &mut UserMeta) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index 06b5154..d3e0e80 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -35,6 +35,8 @@ impl types::GuildMember { /// Adds a role to a guild member. /// + /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. + /// /// # Reference /// See pub async fn add_role( @@ -59,6 +61,8 @@ impl types::GuildMember { /// Removes a role from a guild member. /// + /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. + /// /// # Reference /// See pub async fn remove_role( diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index e76749e..1134332 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -58,6 +58,8 @@ impl types::RoleObject { /// Creates a new role for a given guild. /// + /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. + /// /// # Reference /// See pub async fn create( @@ -86,6 +88,8 @@ impl types::RoleObject { /// Updates the position of a role in a given guild's hierarchy. /// + /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. + /// /// # Reference /// See pub async fn position_update( @@ -116,6 +120,8 @@ impl types::RoleObject { /// Updates a role in a guild. /// + /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. + /// /// # Reference /// See pub async fn update( diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index 343f44d..948a785 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -11,10 +11,8 @@ impl UserMeta { /// /// Note that the session ID is required for guest invites. /// - /// May fire a Guild Create, Channel Create, and/or Relationship Add Gateway event. - /// /// # Reference: - /// Read + /// See pub async fn accept_invite( &mut self, invite_code: &str, @@ -43,7 +41,7 @@ impl UserMeta { /// Note: Spacebar does not yet implement this endpoint. /// /// # Reference: - /// Read + /// See pub async fn create_user_invite(&mut self, code: Option<&str>) -> ChorusResult { ChorusRequest { request: Client::new() @@ -62,10 +60,10 @@ impl UserMeta { /// Creates a new invite for a guild channel or group DM. /// /// # Guild Channels - /// For guild channels, the endpoint - /// requires the CREATE_INSTANT_INVITE permission. + /// For guild channels, the endpoint requires the [`CREATE_INSTANT_INVITE`](crate::types::PermissionFlags::CRATE_INSTANT_INVITE) permission. /// - /// Guild channel invites also fire an Invite Create Gateway event. + /// # Reference + /// See pub async fn create_channel_invite( &mut self, create_channel_invite_schema: CreateChannelInviteSchema, diff --git a/src/api/policies/instance/instance.rs b/src/api/policies/instance/instance.rs index ae6e5d5..768c7fd 100644 --- a/src/api/policies/instance/instance.rs +++ b/src/api/policies/instance/instance.rs @@ -6,6 +6,12 @@ use crate::types::GeneralConfiguration; impl Instance { /// Gets the instance policies schema. + /// + /// # Notes + /// This is a Spacebar only endpoint. + /// + /// # Reference + /// See pub async fn general_configuration_schema(&self) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/policies/instance/"; let request = match self.client.get(&endpoint_url).send().await { diff --git a/src/api/users/channels.rs b/src/api/users/channels.rs index 806bd9f..faa58ad 100644 --- a/src/api/users/channels.rs +++ b/src/api/users/channels.rs @@ -12,8 +12,11 @@ use crate::{ impl UserMeta { /// Creates a DM channel or group DM channel. /// + /// One recipient creates or returns an existing DM channel, + /// none or multiple recipients create a group DM channel. + /// /// # Reference: - /// Read + /// See pub async fn create_private_channel( &mut self, create_private_channel_schema: PrivateChannelCreateSchema, diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index dd52507..a446029 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -10,8 +10,10 @@ impl UserMeta { /// Leaves a given guild. /// /// # Reference: - /// Read - // TODO: Docs: What is lurking here? + /// See + // TODO: Docs: What is "lurking" here? + // It is documented as "Whether the user is lurking in the guild", + // but that says nothing about what this field actually does / means pub async fn leave_guild(&mut self, guild_id: &Snowflake, lurking: bool) -> ChorusResult<()> { ChorusRequest { request: Client::new() diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 9227737..0389ad3 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -292,6 +292,13 @@ impl ChorusRequest { } } + /// Gets the ratelimit configuration. + /// + /// # Notes + /// This is a spacebar only endpoint. + /// + /// # Reference + /// See pub(crate) async fn get_limits_config(url_api: &str) -> ChorusResult { let request = Client::new() .get(format!("{}/policies/instance/limits/", url_api)) diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index a0e8d14..2a38066 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -5,6 +5,8 @@ use crate::types::Snowflake; #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +/// # Reference +/// See pub struct Emoji { pub id: Option, pub name: Option, diff --git a/src/types/entities/guild_member.rs b/src/types/entities/guild_member.rs index 01f43de..b613800 100644 --- a/src/types/entities/guild_member.rs +++ b/src/types/entities/guild_member.rs @@ -3,6 +3,10 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::PublicUser, Snowflake}; #[derive(Debug, Deserialize, Default, Serialize, Clone, PartialEq, Eq)] +/// Represents a participating user in a guild. +/// +/// # Reference +/// See pub struct GuildMember { pub user: Option, pub nick: Option, diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 41d24b6..6e14a59 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -1,5 +1,3 @@ - - use serde::{Deserialize, Serialize}; use crate::types::{ @@ -12,6 +10,10 @@ use crate::types::{ #[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +/// Represents a message sent in a channel. +/// +/// # Reference +/// See pub struct Message { pub id: Snowflake, pub channel_id: Snowflake, @@ -66,6 +68,8 @@ pub struct Message { } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +/// # Reference +/// See pub struct MessageReference { pub message_id: Snowflake, pub channel_id: Snowflake, @@ -201,6 +205,8 @@ pub enum Component { } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +/// # Reference +/// See pub struct MessageActivity { #[serde(rename = "type")] pub activity_type: i64, diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index 098394d..6263f48 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -4,6 +4,10 @@ use crate::types::{entities::User, utils::Snowflake}; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +/// Represents a sticker that can be sent in messages. +/// +/// # Reference +/// See pub struct Sticker { #[serde(default)] pub id: Snowflake, @@ -23,6 +27,12 @@ pub struct Sticker { } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +/// A partial sticker object. +/// +/// Represents the smallest amount of data required to render a sticker. +/// +/// # Reference +/// See pub struct StickerItem { pub id: Snowflake, pub name: String, From 261ae6eb4a65537cdc9656c74ee3db3d0d019d86 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:07:56 +0200 Subject: [PATCH 030/237] Goof --- src/api/channels/channels.rs | 4 ++-- src/api/invites/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index ba99a8f..bf2c48c 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -28,7 +28,7 @@ impl Channel { /// Deletes self. /// - /// Requires the [`MANAGE_CHANNEL`](crate::types::PermissionFlags::MANAGE_CHANNEL) permission in a guild, or + /// Requires the [`MANAGE_CHANNELS`](crate::types::PermissionFlags::MANAGE_CHANNELS) permission in a guild, or /// the [`MANAGE_THREADS`](crate::types::PermissionFlags::MANAGE_THREADS) permission if the channel is a thread. /// /// # Reference @@ -50,7 +50,7 @@ impl Channel { /// Modifies a channel with the provided data. /// Returns the new Channel. /// - /// Requires the [`MANAGE_CHANNEL`](crate::types::PermissionFlags::MANAGE_CHANNEL) permission in a guild. + /// Requires the [`MANAGE_CHANNELS`](crate::types::PermissionFlags::MANAGE_CHANNELS) permission in a guild. /// /// If modifying permission overwrites, the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission is required. /// Only permissions you have in the guild or parent channel (if applicable) can be allowed/denied diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index 948a785..9492d8e 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -60,7 +60,7 @@ impl UserMeta { /// Creates a new invite for a guild channel or group DM. /// /// # Guild Channels - /// For guild channels, the endpoint requires the [`CREATE_INSTANT_INVITE`](crate::types::PermissionFlags::CRATE_INSTANT_INVITE) permission. + /// For guild channels, the endpoint requires the [`CREATE_INSTANT_INVITE`](crate::types::PermissionFlags::CREATE_INSTANT_INVITE) permission. /// /// # Reference /// See From c0bc2ee9e240fbcb6e99b30310857f540c0e83bc Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:28:18 +0200 Subject: [PATCH 031/237] Fix missing references to the best of my ability --- src/api/auth/login.rs | 4 +++- src/api/auth/register.rs | 4 +++- src/api/guilds/roles.rs | 4 +++- src/api/users/users.rs | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 4cc58bb..a360170 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -13,7 +13,9 @@ use crate::types::{GatewayIdentifyPayload, LoginResult, LoginSchema}; impl Instance { /// Logs into an existing account on the spacebar server. - // TODO: Couldn't find reference + /// + /// # Reference + /// See pub async fn login_account(&mut self, login_schema: &LoginSchema) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/login"; let chorus_request = ChorusRequest { diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index ae41c47..f1f279e 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -15,7 +15,9 @@ use crate::{ impl Instance { /// Registers a new user on the server. - // TODO: Couldn't find reference + /// + /// # Reference + /// See pub async fn register_account( &mut self, register_schema: &RegisterSchema, diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 1134332..2787400 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -35,7 +35,9 @@ impl types::RoleObject { } /// Retrieves a single role for a given guild. - // TODO: Couldn't find reference + /// + /// # Reference + /// See pub async fn get( user: &mut UserMeta, guild_id: Snowflake, diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 16c2560..3d95e54 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -110,7 +110,9 @@ impl User { } /// Gets the user's settings. - // TODO: Couldn't find reference + /// + /// # Reference + /// See pub async fn get_settings( token: &String, url_api: &String, From 2739a7479b02b4404d5ad9415af49c40c4267f9d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 1 Aug 2023 21:21:00 +0200 Subject: [PATCH 032/237] Exclude all Target dirs --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d3170e2..1bb4c89 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Generated by Cargo # will have compiled files and executables -/target/ +/**/target/ # These are backup files generated by rustfmt **/*.rs.bk From 917f1cfb0db52ae150988657a215b424afc2eea3 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 2 Aug 2023 20:17:36 +0200 Subject: [PATCH 033/237] Add rc feature to serde --- Cargo.toml | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8dbb172..6c15102 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,19 +10,19 @@ backend = ["poem", "sqlx"] client = [] [dependencies] -tokio = {version = "1.29.1", features = ["macros"]} -serde = {version = "1.0.171", features = ["derive"]} -serde_json = {version= "1.0.103", features = ["raw_value"]} +tokio = { version = "1.29.1", features = ["macros"] } +serde = { version = "1.0.171", features = ["derive", "rc"] } +serde_json = { version = "1.0.103", features = ["raw_value"] } serde-aux = "4.2.0" serde_with = "3.0.0" serde_repr = "0.1.14" -reqwest = {version = "0.11.18", features = ["multipart"]} +reqwest = { version = "0.11.18", features = ["multipart"] } url = "2.4.0" -chrono = {version = "0.4.26", features = ["serde"]} +chrono = { version = "0.4.26", features = ["serde"] } regex = "1.9.1" custom_error = "1.9.2" native-tls = "0.2.11" -tokio-tungstenite = {version = "0.19.0", features = ["native-tls"]} +tokio-tungstenite = { version = "0.19.0", features = ["native-tls"] } futures-util = "0.3.28" http = "0.2.9" openssl = "0.10.55" @@ -31,14 +31,22 @@ hostname = "0.3.1" bitflags = { version = "2.3.3", features = ["serde"] } lazy_static = "1.4.0" poem = { version = "1.3.56", optional = true } -sqlx = { git = "https://github.com/zert3x/sqlx", branch="feature/skip", features = ["mysql", "sqlite", "json", "chrono", "ipnetwork", "runtime-tokio-native-tls", "any"], optional = true } +sqlx = { git = "https://github.com/zert3x/sqlx", branch = "feature/skip", features = [ + "mysql", + "sqlite", + "json", + "chrono", + "ipnetwork", + "runtime-tokio-native-tls", + "any", +], optional = true } thiserror = "1.0.43" jsonwebtoken = "8.3.0" log = "0.4.19" async-trait = "0.1.71" -chorus-macros = {path = "chorus-macros"} +chorus-macros = { path = "chorus-macros" } [dev-dependencies] -tokio = {version = "1.29.1", features = ["full"]} +tokio = { version = "1.29.1", features = ["full"] } lazy_static = "1.4.0" rusty-hook = "0.11.2" From 9f69f576354b992eb88c340f5a04cd2bb8aa6db3 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 2 Aug 2023 20:18:16 +0200 Subject: [PATCH 034/237] Start component-izing entities, remove PartialEq wherever needed (because PartialEq isn't implemented for Mutex) --- src/types/entities/application.rs | 40 +++++++++++----------- src/types/entities/attachment.rs | 2 +- src/types/entities/audit_log.rs | 4 ++- src/types/entities/auto_moderation.rs | 8 +++-- src/types/entities/channel.rs | 48 +++++++++++++++++++++++---- src/types/entities/emoji.rs | 2 +- src/types/entities/guild.rs | 16 +++++---- src/types/entities/guild_member.rs | 2 +- src/types/entities/invite.rs | 2 +- src/types/entities/message.rs | 34 +++++++++---------- src/types/entities/relationship.rs | 11 +++++- src/types/entities/role.rs | 6 ++-- src/types/entities/security_key.rs | 2 +- src/types/entities/sticker.rs | 4 +-- src/types/entities/team.rs | 4 +-- src/types/entities/template.rs | 2 +- src/types/entities/user.rs | 8 ++--- src/types/entities/user_settings.rs | 12 +++---- src/types/entities/voice_state.rs | 2 +- src/types/entities/webhook.rs | 2 +- src/types/schema/channel.rs | 4 +-- 21 files changed, 133 insertions(+), 82 deletions(-) diff --git a/src/types/entities/application.rs b/src/types/entities/application.rs index d4805e9..ee33bd1 100644 --- a/src/types/entities/application.rs +++ b/src/types/entities/application.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use bitflags::bitflags; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -6,7 +8,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; use crate::types::utils::Snowflake; use crate::types::{Team, User}; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See @@ -25,7 +27,7 @@ pub struct Application { pub bot_require_code_grant: bool, pub verify_key: String, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub owner: User, + pub owner: Arc>, pub flags: u64, #[cfg(feature = "sqlx")] pub redirect_uris: Option>>, @@ -47,7 +49,7 @@ pub struct Application { #[cfg(feature = "sqlx")] pub install_params: Option>, #[cfg(not(feature = "sqlx"))] - pub install_params: Option, + pub install_params: Option>>, pub terms_of_service_url: Option, pub privacy_policy_url: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] @@ -94,7 +96,7 @@ impl Application { } } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] /// # Reference /// See pub struct InstallParams { @@ -103,7 +105,7 @@ pub struct InstallParams { } bitflags! { - #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] + #[derive(Debug, Clone, Copy, Serialize, Deserialize)] /// # Reference /// See pub struct ApplicationFlags: u64 { @@ -132,7 +134,7 @@ bitflags! { } } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] /// # Reference /// See pub struct ApplicationCommand { @@ -140,10 +142,10 @@ pub struct ApplicationCommand { pub application_id: Snowflake, pub name: String, pub description: String, - pub options: Vec, + pub options: Vec>>, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] /// Reference /// See pub struct ApplicationCommandOption { @@ -152,16 +154,16 @@ pub struct ApplicationCommandOption { pub description: String, pub required: bool, pub choices: Vec, - pub options: Vec, + pub options: Arc>>, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationCommandOptionChoice { pub name: String, pub value: Value, } -#[derive(Debug, Clone, Copy, PartialEq, Serialize_repr, Deserialize_repr)] +#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[repr(i32)] /// # Reference @@ -184,30 +186,30 @@ pub enum ApplicationCommandOptionType { Attachment = 11, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationCommandInteractionData { pub id: Snowflake, pub name: String, - pub options: Vec, + pub options: Vec>>, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationCommandInteractionDataOption { pub name: String, pub value: Value, - pub options: Vec, + pub options: Vec>>, } -#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, Serialize, Deserialize)] /// See pub struct GuildApplicationCommandPermissions { pub id: Snowflake, pub application_id: Snowflake, pub guild_id: Snowflake, - pub permissions: Vec, + pub permissions: Vec>>, } -#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, Serialize, Deserialize)] /// See pub struct ApplicationCommandPermission { pub id: Snowflake, @@ -217,7 +219,7 @@ pub struct ApplicationCommandPermission { pub permission: bool, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, PartialEq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[repr(u8)] /// See diff --git a/src/types/entities/attachment.rs b/src/types/entities/attachment.rs index 75ec860..8dce564 100644 --- a/src/types/entities/attachment.rs +++ b/src/types/entities/attachment.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See diff --git a/src/types/entities/audit_log.rs b/src/types/entities/audit_log.rs index 8965a05..e0d05e3 100644 --- a/src/types/entities/audit_log.rs +++ b/src/types/entities/audit_log.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; @@ -6,7 +8,7 @@ use crate::types::utils::Snowflake; /// See pub struct AuditLogEntry { pub target_id: Option, - pub changes: Option>, + pub changes: Option>>>, pub user_id: Option, pub id: Snowflake, // to:do implement an enum for these types diff --git a/src/types/entities/auto_moderation.rs b/src/types/entities/auto_moderation.rs index 0feadde..afb1ec6 100644 --- a/src/types/entities/auto_moderation.rs +++ b/src/types/entities/auto_moderation.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -12,8 +14,8 @@ pub struct AutoModerationRule { pub creator_id: Snowflake, pub event_type: AutoModerationRuleEventType, pub trigger_type: AutoModerationRuleTriggerType, - pub trigger_metadata: AutoModerationRuleTriggerMetadata, - pub actions: Vec, + pub trigger_metadata: Arc>, + pub actions: Vec>>, pub enabled: bool, pub exempt_roles: Vec, pub exempt_channels: Vec, @@ -90,7 +92,7 @@ pub enum AutoModerationRuleKeywordPresetType { pub struct AutoModerationAction { #[serde(rename = "type")] pub action_type: AutoModerationActionType, - pub metadata: Option, + pub metadata: Option>>, } #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 60304f9..8bc803e 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -10,7 +10,7 @@ use crate::types::{ utils::Snowflake, }; -#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Updateable)] +#[derive(Default, Debug, Serialize, Deserialize, Clone, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// Represents a guild of private channel /// @@ -71,7 +71,41 @@ pub struct Channel { pub video_quality_mode: Option, } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +impl PartialEq for Channel { + fn eq(&self, other: &Self) -> bool { + self.application_id == other.application_id + && self.bitrate == other.bitrate + && self.channel_type == other.channel_type + && self.created_at == other.created_at + && self.default_auto_archive_duration == other.default_auto_archive_duration + && self.default_forum_layout == other.default_forum_layout + && self.default_sort_order == other.default_sort_order + && self.default_thread_rate_limit_per_user == other.default_thread_rate_limit_per_user + && self.flags == other.flags + && self.guild_id == other.guild_id + && self.icon == other.icon + && self.id == other.id + && self.last_message_id == other.last_message_id + && self.last_pin_timestamp == other.last_pin_timestamp + && self.managed == other.managed + && self.member_count == other.member_count + && self.message_count == other.message_count + && self.name == other.name + && self.nsfw == other.nsfw + && self.owner_id == other.owner_id + && self.parent_id == other.parent_id + && self.permissions == other.permissions + && self.position == other.position + && self.rate_limit_per_user == other.rate_limit_per_user + && self.rtc_region == other.rtc_region + && self.topic == other.topic + && self.total_message_sent == other.total_message_sent + && self.user_limit == other.user_limit + && self.video_quality_mode == other.video_quality_mode + } +} + +#[derive(Debug, Deserialize, Serialize, Clone)] /// A tag that can be applied to a thread in a [ChannelType::GuildForum] or [ChannelType::GuildMedia] channel. /// /// # Reference @@ -86,7 +120,7 @@ pub struct Tag { pub emoji_name: Option, } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct PermissionOverwrite { pub id: Snowflake, #[serde(rename = "type")] @@ -100,7 +134,7 @@ pub struct PermissionOverwrite { pub deny: String, } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Clone)] /// # Reference /// See pub struct ThreadMetadata { @@ -112,7 +146,7 @@ pub struct ThreadMetadata { pub create_timestamp: Option, } -#[derive(Default, Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +#[derive(Default, Debug, Deserialize, Serialize, Clone)] /// # Reference /// See pub struct ThreadMember { @@ -123,7 +157,7 @@ pub struct ThreadMember { pub member: Option, } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Clone)] /// Specifies the emoji to use as the default way to react to a [ChannelType::GuildForum] or [ChannelType::GuildMedia] channel post. /// /// # Reference @@ -134,7 +168,7 @@ pub struct DefaultReaction { pub emoji_name: Option, } -#[derive(Default, Clone, Copy, Debug, Serialize_repr, Deserialize_repr, PartialEq, Eq)] +#[derive(Default, Clone, Copy, Debug, Serialize_repr, Deserialize_repr, PartialEq)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[repr(i32)] diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 2a38066..f3e8434 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::User; use crate::types::Snowflake; -#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)] +#[derive(Debug, Clone, Deserialize, Serialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index f9bddd2..827701a 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -10,7 +12,7 @@ use crate::types::{ }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Guild { pub afk_channel_id: Option, @@ -25,13 +27,13 @@ pub struct Guild { #[cfg_attr(feature = "sqlx", sqlx(skip))] pub bans: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub channels: Option>, + pub channels: Option>>>, pub default_message_notifications: Option, pub description: Option, pub discovery_splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] #[serde(default)] - pub emojis: Vec, + pub emojis: Vec>>, pub explicit_content_filter: Option, //#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))] pub features: Option, @@ -91,7 +93,7 @@ pub struct Guild { } /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildBan { pub user_id: Snowflake, @@ -100,7 +102,7 @@ pub struct GuildBan { } /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildInvite { pub code: String, @@ -122,13 +124,13 @@ pub struct GuildInvite { pub vanity_url: Option, } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] pub struct UnavailableGuild { id: Snowflake, unavailable: bool, } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] pub struct GuildCreateResponse { pub id: Snowflake, } diff --git a/src/types/entities/guild_member.rs b/src/types/entities/guild_member.rs index b613800..12ffcdc 100644 --- a/src/types/entities/guild_member.rs +++ b/src/types/entities/guild_member.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::PublicUser, Snowflake}; -#[derive(Debug, Deserialize, Default, Serialize, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Default, Serialize, Clone)] /// Represents a participating user in a guild. /// /// # Reference diff --git a/src/types/entities/invite.rs b/src/types/entities/invite.rs index 6d7b570..5a2e0cd 100644 --- a/src/types/entities/invite.rs +++ b/src/types/entities/invite.rs @@ -56,7 +56,7 @@ pub struct InviteGuild { /// See for an explanation on what /// the levels mean. -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum NSFWLevel { Default = 0, diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 6e14a59..34a39c7 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -8,7 +8,7 @@ use crate::types::{ utils::Snowflake, }; -#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)] +#[derive(Debug, Serialize, Deserialize, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// Represents a message sent in a channel. /// @@ -67,7 +67,7 @@ pub struct Message { pub role_subscription_data: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] /// # Reference /// See pub struct MessageReference { @@ -77,7 +77,7 @@ pub struct MessageReference { pub fail_if_not_exists: Option, } -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct MessageInteraction { pub id: Snowflake, #[serde(rename = "type")] @@ -87,7 +87,7 @@ pub struct MessageInteraction { pub member: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct AllowedMention { parse: Vec, roles: Vec, @@ -95,7 +95,7 @@ pub struct AllowedMention { replied_user: bool, } -#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum AllowedMentionType { Roles, @@ -103,7 +103,7 @@ pub enum AllowedMentionType { Everyone, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ChannelMention { pub id: Snowflake, pub guild_id: Snowflake, @@ -112,7 +112,7 @@ pub struct ChannelMention { name: String, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Embed { title: Option, #[serde(rename = "type")] @@ -130,14 +130,14 @@ pub struct Embed { fields: Option>, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmbedFooter { text: String, icon_url: Option, proxy_icon_url: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmbedImage { url: String, proxy_url: String, @@ -145,7 +145,7 @@ pub struct EmbedImage { width: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmbedThumbnail { url: String, proxy_url: Option, @@ -153,7 +153,7 @@ pub struct EmbedThumbnail { width: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] struct EmbedVideo { url: Option, proxy_url: Option, @@ -161,13 +161,13 @@ struct EmbedVideo { width: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmbedProvider { name: Option, url: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmbedAuthor { name: String, url: Option, @@ -175,14 +175,14 @@ pub struct EmbedAuthor { proxy_icon_url: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmbedField { name: String, value: String, inline: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Reaction { pub count: u32, pub burst_count: u32, @@ -192,7 +192,7 @@ pub struct Reaction { pub emoji: Emoji, } -#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum Component { ActionRow = 1, Button = 2, @@ -204,7 +204,7 @@ pub enum Component { ChannelSelect = 8, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] /// # Reference /// See pub struct MessageActivity { diff --git a/src/types/entities/relationship.rs b/src/types/entities/relationship.rs index 168f362..a184f24 100644 --- a/src/types/entities/relationship.rs +++ b/src/types/entities/relationship.rs @@ -6,7 +6,7 @@ use crate::types::Snowflake; use super::PublicUser; -#[derive(Debug, Deserialize, Serialize, Clone, Default, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Clone, Default)] /// See pub struct Relationship { pub id: Snowflake, @@ -17,6 +17,15 @@ pub struct Relationship { pub since: Option>, } +impl PartialEq for Relationship { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + && self.relationship_type == other.relationship_type + && self.since == other.since + && self.nickname == other.nickname + } +} + #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default, Eq, PartialEq)] #[repr(u8)] /// See diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 0748453..af2430f 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -26,7 +26,7 @@ pub struct RoleObject { pub tags: Option, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct RoleSubscriptionData { pub role_subscription_listing_id: Snowflake, pub tier_name: String, @@ -34,7 +34,7 @@ pub struct RoleSubscriptionData { pub is_renewal: bool, } -#[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)] /// See pub struct RoleTags { #[serde(default)] @@ -53,7 +53,7 @@ pub struct RoleTags { } bitflags! { - #[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] + #[derive(Debug, Default, Clone, Hash, Serialize, Deserialize)] /// Permissions limit what users of certain roles can do on a Guild to Guild basis. /// /// # Reference: diff --git a/src/types/entities/security_key.rs b/src/types/entities/security_key.rs index 2cf8f66..9ffbafa 100644 --- a/src/types/entities/security_key.rs +++ b/src/types/entities/security_key.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct SecurityKey { pub id: String, diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index 6263f48..5f29d2b 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::User, utils::Snowflake}; -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[derive(Debug, Serialize, Deserialize, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// Represents a sticker that can be sent in messages. /// @@ -26,7 +26,7 @@ pub struct Sticker { pub sort_value: Option, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] /// A partial sticker object. /// /// Represents the smallest amount of data required to render a sticker. diff --git a/src/types/entities/team.rs b/src/types/entities/team.rs index a6f2ef1..4cce7ac 100644 --- a/src/types/entities/team.rs +++ b/src/types/entities/team.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::User; use crate::types::Snowflake; -#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Team { pub icon: Option, @@ -14,7 +14,7 @@ pub struct Team { pub owner_user_id: Snowflake, } -#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone)] pub struct TeamMember { pub membership_state: u8, pub permissions: Vec, diff --git a/src/types/entities/template.rs b/src/types/entities/template.rs index 2f934c9..85b7dd2 100644 --- a/src/types/entities/template.rs +++ b/src/types/entities/template.rs @@ -7,7 +7,7 @@ use crate::types::{ }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildTemplate { pub code: String, diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 469c45e..3e1afeb 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -3,7 +3,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] pub struct UserData { pub valid_tokens_since: DateTime, @@ -15,7 +15,7 @@ impl User { PublicUser::from(self) } } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct User { pub id: Snowflake, @@ -50,7 +50,7 @@ pub struct User { pub disabled: Option, } -#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct PublicUser { pub id: Snowflake, pub username: Option, @@ -91,7 +91,7 @@ impl From for PublicUser { const CUSTOM_USER_FLAG_OFFSET: u64 = 1 << 32; bitflags::bitflags! { - #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] + #[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] pub struct UserFlags: u64 { const DISCORD_EMPLOYEE = 1 << 0; diff --git a/src/types/entities/user_settings.rs b/src/types/entities/user_settings.rs index 40b936a..09d1c6e 100644 --- a/src/types/entities/user_settings.rs +++ b/src/types/entities/user_settings.rs @@ -1,7 +1,7 @@ use chrono::{serde::ts_milliseconds_option, Utc}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "lowercase")] pub enum UserStatus { @@ -19,7 +19,7 @@ impl std::fmt::Display for UserStatus { } } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "lowercase")] pub enum UserTheme { @@ -28,7 +28,7 @@ pub enum UserTheme { Light, } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct UserSettings { pub afk_timeout: u16, @@ -117,7 +117,7 @@ impl Default for UserSettings { } } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct CustomStatus { pub emoji_id: Option, @@ -127,7 +127,7 @@ pub struct CustomStatus { pub text: Option, } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct FriendSourceFlags { pub all: bool, } @@ -138,7 +138,7 @@ impl Default for FriendSourceFlags { } } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct GuildFolder { pub color: u32, pub guild_ids: Vec, diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index 94d3d79..11699b6 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -7,7 +7,7 @@ use crate::types::{ }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct VoiceState { pub guild_id: Option, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index f953149..7e4a6ef 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -6,7 +6,7 @@ use crate::types::{ }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Webhook { pub id: Snowflake, diff --git a/src/types/schema/channel.rs b/src/types/schema/channel.rs index 27c78ee..e7261cb 100644 --- a/src/types/schema/channel.rs +++ b/src/types/schema/channel.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::PermissionOverwrite, Snowflake}; -#[derive(Debug, Deserialize, Serialize, Default, PartialEq, PartialOrd)] +#[derive(Debug, Deserialize, Serialize, Default)] #[serde(rename_all = "snake_case")] pub struct ChannelCreateSchema { pub name: String, @@ -27,7 +27,7 @@ pub struct ChannelCreateSchema { pub video_quality_mode: Option, } -#[derive(Debug, Deserialize, Serialize, Clone, Default, PartialEq, PartialOrd)] +#[derive(Debug, Deserialize, Serialize, Clone, Default)] #[serde(rename_all = "snake_case")] pub struct ChannelModifySchema { pub name: Option, From a36d691fea557a1116b41a3a683f9622f3cf9380 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 2 Aug 2023 20:23:50 +0200 Subject: [PATCH 035/237] Add PartialEq, Eq, Hash to Enums --- src/types/entities/application.rs | 6 +++--- src/types/entities/channel.rs | 2 +- src/types/entities/role.rs | 2 +- src/types/entities/user.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/types/entities/application.rs b/src/types/entities/application.rs index ee33bd1..ec3c7fb 100644 --- a/src/types/entities/application.rs +++ b/src/types/entities/application.rs @@ -105,7 +105,7 @@ pub struct InstallParams { } bitflags! { - #[derive(Debug, Clone, Copy, Serialize, Deserialize)] + #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] /// # Reference /// See pub struct ApplicationFlags: u64 { @@ -163,7 +163,7 @@ pub struct ApplicationCommandOptionChoice { pub value: Value, } -#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr)] +#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr, PartialEq, Eq, Hash)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[repr(i32)] /// # Reference @@ -219,7 +219,7 @@ pub struct ApplicationCommandPermission { pub permission: bool, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, PartialEq, Eq, Hash)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[repr(u8)] /// See diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 8bc803e..f9a4b4a 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -168,7 +168,7 @@ pub struct DefaultReaction { pub emoji_name: Option, } -#[derive(Default, Clone, Copy, Debug, Serialize_repr, Deserialize_repr, PartialEq)] +#[derive(Default, Clone, Copy, Debug, Serialize_repr, Deserialize_repr, PartialEq, Eq, Hash)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[repr(i32)] diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index af2430f..3f74218 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -53,7 +53,7 @@ pub struct RoleTags { } bitflags! { - #[derive(Debug, Default, Clone, Hash, Serialize, Deserialize)] + #[derive(Debug, Default, Clone, Hash, Serialize, Deserialize, PartialEq, Eq)] /// Permissions limit what users of certain roles can do on a Guild to Guild basis. /// /// # Reference: diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 3e1afeb..0adb363 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -91,7 +91,7 @@ impl From for PublicUser { const CUSTOM_USER_FLAG_OFFSET: u64 = 1 << 32; bitflags::bitflags! { - #[derive(Debug, Clone, Copy, Serialize, Deserialize)] + #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] pub struct UserFlags: u64 { const DISCORD_EMPLOYEE = 1 << 0; From 94eac6eba9cb5946e3349dc96af215fa7af1c240 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 2 Aug 2023 23:08:53 +0200 Subject: [PATCH 036/237] Make components be Arc> --- src/types/entities/channel.rs | 10 ++++++---- src/types/entities/emoji.rs | 4 +++- src/types/entities/guild.rs | 18 +++++++++--------- src/types/entities/guild_member.rs | 4 +++- src/types/entities/integration.rs | 6 ++++-- src/types/entities/invite.rs | 4 +++- src/types/entities/relationship.rs | 4 +++- src/types/entities/sticker.rs | 4 +++- src/types/entities/team.rs | 4 +++- src/types/entities/template.rs | 8 +++++--- src/types/entities/user_settings.rs | 8 +++++--- src/types/entities/voice_state.rs | 4 +++- src/types/entities/webhook.rs | 6 ++++-- 13 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index f9a4b4a..0e66ed3 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chorus_macros::Updateable; use chrono::Utc; use serde::{Deserialize, Serialize}; @@ -46,7 +48,7 @@ pub struct Channel { pub last_pin_timestamp: Option, pub managed: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub member: Option, + pub member: Option>>, pub member_count: Option, pub message_count: Option, pub name: Option, @@ -56,12 +58,12 @@ pub struct Channel { #[cfg(feature = "sqlx")] pub permission_overwrites: Option>>, #[cfg(not(feature = "sqlx"))] - pub permission_overwrites: Option>, + pub permission_overwrites: Option>>>, pub permissions: Option, pub position: Option, pub rate_limit_per_user: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub recipients: Option>, + pub recipients: Option>>>, pub rtc_region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub thread_metadata: Option, @@ -154,7 +156,7 @@ pub struct ThreadMember { pub user_id: Option, pub join_timestamp: Option, pub flags: Option, - pub member: Option, + pub member: Option>>, } #[derive(Debug, Deserialize, Serialize, Clone)] diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index f3e8434..38d7da7 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use serde::{Deserialize, Serialize}; use crate::types::entities::User; @@ -15,7 +17,7 @@ pub struct Emoji { #[cfg(not(feature = "sqlx"))] pub roles: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option, + pub user: Option>>, pub require_colons: Option, pub managed: Option, pub animated: Option, diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 827701a..ae59e49 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -42,7 +42,7 @@ pub struct Guild { pub icon_hash: Option, pub id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub invites: Option>, + pub invites: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub joined_at: Option, pub large: Option, @@ -68,7 +68,7 @@ pub struct Guild { pub public_updates_channel_id: Option, pub region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub roles: Option>, + pub roles: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub rules_channel: Option, pub rules_channel_id: Option, @@ -81,13 +81,13 @@ pub struct Guild { pub vanity_url_code: Option, pub verification_level: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub voice_states: Option>, + pub voice_states: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub webhooks: Option>, + pub webhooks: Option>>>, #[cfg(feature = "sqlx")] pub welcome_screen: Option>, #[cfg(not(feature = "sqlx"))] - pub welcome_screen: Option, + pub welcome_screen: Option>>, pub widget_channel_id: Option, pub widget_enabled: Option, } @@ -113,11 +113,11 @@ pub struct GuildInvite { pub created_at: DateTime, pub expires_at: Option>, pub guild_id: Snowflake, - pub guild: Option, + pub guild: Option>>, pub channel_id: Snowflake, - pub channel: Option, + pub channel: Option>>, pub inviter_id: Option, - pub inviter: Option, + pub inviter: Option>>, pub target_user_id: Option, pub target_user: Option, pub target_user_type: Option, @@ -151,7 +151,7 @@ pub struct GuildScheduledEvent { pub entity_type: GuildScheduledEventEntityType, pub entity_id: Option, pub entity_metadata: Option, - pub creator: Option, + pub creator: Option>>, pub user_count: Option, pub image: Option, } diff --git a/src/types/entities/guild_member.rs b/src/types/entities/guild_member.rs index 12ffcdc..af63cfb 100644 --- a/src/types/entities/guild_member.rs +++ b/src/types/entities/guild_member.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use serde::{Deserialize, Serialize}; use crate::types::{entities::PublicUser, Snowflake}; @@ -8,7 +10,7 @@ use crate::types::{entities::PublicUser, Snowflake}; /// # Reference /// See pub struct GuildMember { - pub user: Option, + pub user: Option>>, pub nick: Option, pub avatar: Option, pub roles: Vec, diff --git a/src/types/entities/integration.rs b/src/types/entities/integration.rs index f083dae..a95c33c 100644 --- a/src/types/entities/integration.rs +++ b/src/types/entities/integration.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -21,14 +23,14 @@ pub struct Integration { pub expire_behaviour: Option, pub expire_grace_period: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option, + pub user: Option>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub account: IntegrationAccount, pub synced_at: Option>, pub subscriber_count: Option, pub revoked: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub application: Option, + pub application: Option>>, pub scopes: Option>, } diff --git a/src/types/entities/invite.rs b/src/types/entities/invite.rs index 5a2e0cd..fe2444d 100644 --- a/src/types/entities/invite.rs +++ b/src/types/entities/invite.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -68,7 +70,7 @@ pub enum NSFWLevel { /// See #[derive(Debug, Serialize, Deserialize)] pub struct InviteStageInstance { - pub members: Vec, + pub members: Vec>>, pub participant_count: i32, pub speaker_count: i32, pub topic: String, diff --git a/src/types/entities/relationship.rs b/src/types/entities/relationship.rs index a184f24..a5f5bcb 100644 --- a/src/types/entities/relationship.rs +++ b/src/types/entities/relationship.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -13,7 +15,7 @@ pub struct Relationship { #[serde(rename = "type")] pub relationship_type: RelationshipType, pub nickname: Option, - pub user: PublicUser, + pub user: Arc>, pub since: Option>, } diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index 5f29d2b..cdc1202 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use serde::{Deserialize, Serialize}; use crate::types::{entities::User, utils::Snowflake}; @@ -22,7 +24,7 @@ pub struct Sticker { pub available: Option, pub guild_id: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option, + pub user: Option>>, pub sort_value: Option, } diff --git a/src/types/entities/team.rs b/src/types/entities/team.rs index 4cce7ac..fe6562b 100644 --- a/src/types/entities/team.rs +++ b/src/types/entities/team.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use serde::{Deserialize, Serialize}; use crate::types::entities::User; @@ -19,5 +21,5 @@ pub struct TeamMember { pub membership_state: u8, pub permissions: Vec, pub team_id: Snowflake, - pub user: User, + pub user: Arc>, } diff --git a/src/types/entities/template.rs b/src/types/entities/template.rs index 85b7dd2..0550e9e 100644 --- a/src/types/entities/template.rs +++ b/src/types/entities/template.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -16,13 +18,13 @@ pub struct GuildTemplate { pub usage_count: Option, pub creator_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub creator: User, + pub creator: Arc>, pub created_at: DateTime, pub updated_at: DateTime, pub source_guild_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub source_guild: Vec, + pub source_guild: Vec>>, // Unsure how a {recursive: Guild} looks like, might be a Vec? #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub serialized_source_guild: Vec, + pub serialized_source_guild: Vec>>, } diff --git a/src/types/entities/user_settings.rs b/src/types/entities/user_settings.rs index 09d1c6e..758762b 100644 --- a/src/types/entities/user_settings.rs +++ b/src/types/entities/user_settings.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chrono::{serde::ts_milliseconds_option, Utc}; use serde::{Deserialize, Serialize}; @@ -73,7 +75,7 @@ pub struct UserSettings { #[cfg(not(feature = "sqlx"))] pub restricted_guilds: Vec, pub show_current_game: bool, - pub status: UserStatus, + pub status: Arc>, pub stream_notifications_enabled: bool, pub theme: UserTheme, pub timezone_offset: i16, @@ -109,7 +111,7 @@ impl Default for UserSettings { render_reactions: true, restricted_guilds: Default::default(), show_current_game: true, - status: UserStatus::Online, + status: Arc::new(Mutex::new(UserStatus::Online)), stream_notifications_enabled: false, theme: UserTheme::Dark, timezone_offset: 0, @@ -149,5 +151,5 @@ pub struct GuildFolder { #[derive(Debug, Serialize, Deserialize)] pub struct LoginResult { pub token: String, - pub settings: UserSettings, + pub settings: Arc>, } diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index 11699b6..29b8e6e 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -14,7 +16,7 @@ pub struct VoiceState { pub guild: Option, pub channel_id: Option, pub user_id: Snowflake, - pub member: Option, + pub member: Option>>, pub session_id: Snowflake, pub token: Option, pub deaf: bool, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index 7e4a6ef..f8b6530 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, Mutex}; + use serde::{Deserialize, Serialize}; use crate::types::{ @@ -20,10 +22,10 @@ pub struct Webhook { pub application_id: Snowflake, #[serde(skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option, + pub user: Option>>, #[serde(skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub source_guild: Option, + pub source_guild: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub url: Option, } From fb792f835641d8f6697f3a419dfaf72a0ba7775f Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 11:19:23 +0200 Subject: [PATCH 037/237] Integrate component behaviour everywhere --- src/api/auth/login.rs | 3 +- src/api/auth/register.rs | 5 +-- src/api/users/users.rs | 3 +- src/instance.rs | 13 +++---- tests/channels.rs | 74 ++++++++++++++++++++++++++++++---------- tests/members.rs | 2 +- tests/relationships.rs | 59 ++++++++++++++++++++------------ 7 files changed, 109 insertions(+), 50 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index a360170..447e4c0 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; +use std::sync::{Arc, Mutex}; use reqwest::Client; use serde_json::to_string; @@ -45,7 +46,7 @@ impl Instance { login_result.token, self.clone_limits_if_some(), login_result.settings, - object, + Arc::new(Mutex::new(object)), gateway, ); Ok(user) diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index f1f279e..ea74f29 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -1,3 +1,4 @@ +use std::sync::{Arc, Mutex}; use std::{cell::RefCell, rc::Rc}; use reqwest::Client; @@ -51,8 +52,8 @@ impl Instance { Rc::new(RefCell::new(self.clone())), token.clone(), self.clone_limits_if_some(), - settings, - user_object, + Arc::new(Mutex::new(settings)), + Arc::new(Mutex::new(user_object)), gateway, ); Ok(user) diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 3d95e54..03af2f9 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -1,3 +1,4 @@ +use std::sync::{Arc, Mutex}; use std::{cell::RefCell, rc::Rc}; use reqwest::Client; @@ -59,7 +60,7 @@ impl UserMeta { .deserialize_response::(self) .await .unwrap(); - let _ = std::mem::replace(&mut self.object, user_updated.clone()); + self.object = Arc::new(Mutex::new(user_updated.clone())); Ok(user_updated) } diff --git a/src/instance.rs b/src/instance.rs index f034513..5c2e98b 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -2,6 +2,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::fmt; use std::rc::Rc; +use std::sync::{Arc, Mutex}; use reqwest::Client; use serde::{Deserialize, Serialize}; @@ -90,8 +91,8 @@ pub struct UserMeta { pub belongs_to: Rc>, pub token: String, pub limits: Option>, - pub settings: UserSettings, - pub object: User, + pub settings: Arc>, + pub object: Arc>, pub gateway: GatewayHandle, } @@ -113,8 +114,8 @@ impl UserMeta { belongs_to: Rc>, token: String, limits: Option>, - settings: UserSettings, - object: User, + settings: Arc>, + object: Arc>, gateway: GatewayHandle, ) -> UserMeta { UserMeta { @@ -133,8 +134,8 @@ impl UserMeta { /// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify /// first. pub(crate) async fn shell(instance: Rc>, token: String) -> UserMeta { - let settings = UserSettings::default(); - let object = User::default(); + let settings = Arc::new(Mutex::new(UserSettings::default())); + let object = Arc::new(Mutex::new(User::default())); let wss_url = instance.borrow().urls.wss.clone(); // Dummy gateway object let gateway = Gateway::new(wss_url).await.unwrap(); diff --git a/tests/channels.rs b/tests/channels.rs index c8564d7..d810c10 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -59,8 +59,9 @@ async fn modify_channel() { PermissionFlags::MANAGE_CHANNELS, PermissionFlags::MANAGE_MESSAGES, ])); + let user_id: types::Snowflake = bundle.user.object.lock().unwrap().id; let permission_override = PermissionOverwrite { - id: bundle.user.object.id, + id: user_id, overwrite_type: "1".to_string(), allow: permission_override, deny: "0".to_string(), @@ -143,7 +144,7 @@ async fn create_dm() { let other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { - recipients: Some(Vec::from([other_user.object.id])), + recipients: Some(Vec::from([other_user.object.lock().unwrap().id])), access_tokens: None, nicks: None, }; @@ -153,26 +154,47 @@ async fn create_dm() { .unwrap(); assert!(dm_channel.recipients.is_some()); assert_eq!( - dm_channel.recipients.as_ref().unwrap().get(0).unwrap().id, - other_user.object.id + dm_channel + .recipients + .as_ref() + .unwrap() + .get(0) + .unwrap() + .lock() + .unwrap() + .id + .clone(), + other_user.object.lock().unwrap().id ); assert_eq!( - dm_channel.recipients.as_ref().unwrap().get(1).unwrap().id, - user.object.id + dm_channel + .recipients + .as_ref() + .unwrap() + .get(1) + .unwrap() + .lock() + .unwrap() + .id + .clone(), + user.object.lock().unwrap().id.clone() ); common::teardown(bundle).await; } // #[tokio::test] -// This test currently is broken due to an issue with the Spacebar Server. +// TODO This test currently is broken due to an issue with the Spacebar Server. #[allow(dead_code)] async fn remove_add_person_from_to_dm() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let mut third_user = bundle.create_user("integrationtestuser3").await; + let third_user_id = third_user.object.lock().unwrap().id; + let other_user_id = other_user.object.lock().unwrap().id; + let user_id = bundle.user.object.lock().unwrap().id; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { - recipients: Some(Vec::from([other_user.object.id, third_user.object.id])), + recipients: Some(Vec::from([other_user_id, third_user_id])), access_tokens: None, nicks: None, }; @@ -181,36 +203,52 @@ async fn remove_add_person_from_to_dm() { .await .unwrap(); // Creates the Channel and stores the response Channel object dm_channel - .remove_channel_recipient(other_user.object.id, user) + .remove_channel_recipient(other_user_id, user) .await .unwrap(); assert!(dm_channel.recipients.as_ref().unwrap().get(1).is_none()); other_user - .modify_user_relationship(user.object.id, RelationshipType::Friends) + .modify_user_relationship(user_id, RelationshipType::Friends) .await .unwrap(); - user.modify_user_relationship(other_user.object.id, RelationshipType::Friends) + user.modify_user_relationship(other_user_id, RelationshipType::Friends) .await .unwrap(); third_user - .modify_user_relationship(user.object.id, RelationshipType::Friends) + .modify_user_relationship(user_id, RelationshipType::Friends) .await .unwrap(); - user.modify_user_relationship(third_user.object.id, RelationshipType::Friends) + user.modify_user_relationship(third_user_id, RelationshipType::Friends) .await .unwrap(); // Users 1-2 and 1-3 are now friends dm_channel - .add_channel_recipient(other_user.object.id, user, None) + .add_channel_recipient(other_user_id, user, None) .await .unwrap(); assert!(dm_channel.recipients.is_some()); assert_eq!( - dm_channel.recipients.as_ref().unwrap().get(0).unwrap().id, - other_user.object.id + dm_channel + .recipients + .as_ref() + .unwrap() + .get(0) + .unwrap() + .lock() + .unwrap() + .id, + other_user_id ); assert_eq!( - dm_channel.recipients.as_ref().unwrap().get(1).unwrap().id, - user.object.id + dm_channel + .recipients + .as_ref() + .unwrap() + .get(1) + .unwrap() + .lock() + .unwrap() + .id, + user_id ); } diff --git a/tests/members.rs b/tests/members.rs index 9710d7f..a314be7 100644 --- a/tests/members.rs +++ b/tests/members.rs @@ -7,7 +7,7 @@ async fn add_remove_role() -> ChorusResult<()> { let mut bundle = common::setup().await; let guild = bundle.guild.id; let role = bundle.role.id; - let member_id = bundle.user.object.id; + let member_id = bundle.user.object.lock().unwrap().id; GuildMember::add_role(&mut bundle.user, guild, member_id, role).await?; let member = GuildMember::get(&mut bundle.user, guild, member_id) .await diff --git a/tests/relationships.rs b/tests/relationships.rs index 00ef9cf..1bd4976 100644 --- a/tests/relationships.rs +++ b/tests/relationships.rs @@ -7,15 +7,13 @@ async fn test_get_mutual_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; + let other_user_id: types::Snowflake = other_user.object.lock().unwrap().id; let friend_request_schema = types::FriendRequestSendSchema { - username: user.object.username.clone(), - discriminator: Some(user.object.discriminator.clone()), + username: user.object.lock().unwrap().username.clone(), + discriminator: Some(user.object.lock().unwrap().discriminator.clone()), }; let _ = other_user.send_friend_request(friend_request_schema).await; - let relationships = user - .get_mutual_relationships(other_user.object.id) - .await - .unwrap(); + let relationships = user.get_mutual_relationships(other_user_id).await.unwrap(); println!("{:?}", relationships); common::teardown(bundle).await } @@ -26,15 +24,18 @@ async fn test_get_relationships() { let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; let friend_request_schema = types::FriendRequestSendSchema { - username: user.object.username.clone(), - discriminator: Some(user.object.discriminator.clone()), + username: user.object.lock().unwrap().username.clone(), + discriminator: Some(user.object.lock().unwrap().discriminator.clone()), }; other_user .send_friend_request(friend_request_schema) .await .unwrap(); let relationships = user.get_relationships().await.unwrap(); - assert_eq!(relationships.get(0).unwrap().id, other_user.object.id); + assert_eq!( + relationships.get(0).unwrap().id, + other_user.object.lock().unwrap().id + ); common::teardown(bundle).await } @@ -43,23 +44,33 @@ async fn test_modify_relationship_friends() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let _ = other_user - .modify_user_relationship(user.object.id, types::RelationshipType::Friends) - .await; + let user_id: types::Snowflake = user.object.lock().unwrap().id; + let other_user_id: types::Snowflake = other_user.object.lock().unwrap().id; + + other_user + .modify_user_relationship(user_id, types::RelationshipType::Friends) + .await + .unwrap(); let relationships = user.get_relationships().await.unwrap(); - assert_eq!(relationships.get(0).unwrap().id, other_user.object.id); + assert_eq!( + relationships.get(0).unwrap().id, + other_user.object.lock().unwrap().id + ); assert_eq!( relationships.get(0).unwrap().relationship_type, RelationshipType::Incoming ); let relationships = other_user.get_relationships().await.unwrap(); - assert_eq!(relationships.get(0).unwrap().id, user.object.id); + assert_eq!( + relationships.get(0).unwrap().id, + user.object.lock().unwrap().id + ); assert_eq!( relationships.get(0).unwrap().relationship_type, RelationshipType::Outgoing ); let _ = user - .modify_user_relationship(other_user.object.id, RelationshipType::Friends) + .modify_user_relationship(other_user_id, RelationshipType::Friends) .await; assert_eq!( other_user @@ -71,7 +82,7 @@ async fn test_modify_relationship_friends() { .relationship_type, RelationshipType::Friends ); - let _ = user.remove_relationship(other_user.object.id).await; + let _ = user.remove_relationship(other_user_id).await; assert_eq!( other_user.get_relationships().await.unwrap(), Vec::::new() @@ -84,18 +95,24 @@ async fn test_modify_relationship_block() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let _ = other_user - .modify_user_relationship(user.object.id, types::RelationshipType::Blocked) - .await; + let user_id: types::Snowflake = user.object.lock().unwrap().id; + + other_user + .modify_user_relationship(user_id, types::RelationshipType::Blocked) + .await + .unwrap(); let relationships = user.get_relationships().await.unwrap(); assert_eq!(relationships, Vec::::new()); let relationships = other_user.get_relationships().await.unwrap(); - assert_eq!(relationships.get(0).unwrap().id, user.object.id); + assert_eq!( + relationships.get(0).unwrap().id, + user.object.lock().unwrap().id + ); assert_eq!( relationships.get(0).unwrap().relationship_type, RelationshipType::Blocked ); - let _ = other_user.remove_relationship(user.object.id).await; + other_user.remove_relationship(user_id).await.unwrap(); assert_eq!( other_user.get_relationships().await.unwrap(), Vec::::new() From 420c2f7727f034f11cf55d25c0a965400cf66a5b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 11:34:03 +0200 Subject: [PATCH 038/237] Fix deadlock in test_get_relationships --- tests/relationships.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/relationships.rs b/tests/relationships.rs index 1bd4976..951d134 100644 --- a/tests/relationships.rs +++ b/tests/relationships.rs @@ -23,9 +23,11 @@ async fn test_get_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; + let username = user.object.lock().unwrap().username.clone(); + let discriminator = user.object.lock().unwrap().discriminator.clone(); let friend_request_schema = types::FriendRequestSendSchema { - username: user.object.lock().unwrap().username.clone(), - discriminator: Some(user.object.lock().unwrap().discriminator.clone()), + username, + discriminator: Some(discriminator), }; other_user .send_friend_request(friend_request_schema) From 98188eadc465ebcc065c7a8a21f19ea984cc1b82 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 11:42:28 +0200 Subject: [PATCH 039/237] Fix deadlock on test_get_mutual_relationships --- tests/relationships.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/relationships.rs b/tests/relationships.rs index 951d134..2773474 100644 --- a/tests/relationships.rs +++ b/tests/relationships.rs @@ -7,12 +7,17 @@ async fn test_get_mutual_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; + let username = user.object.lock().unwrap().username.clone(); + let discriminator = user.object.lock().unwrap().discriminator.clone(); let other_user_id: types::Snowflake = other_user.object.lock().unwrap().id; let friend_request_schema = types::FriendRequestSendSchema { - username: user.object.lock().unwrap().username.clone(), - discriminator: Some(user.object.lock().unwrap().discriminator.clone()), + username, + discriminator: Some(discriminator), }; - let _ = other_user.send_friend_request(friend_request_schema).await; + other_user + .send_friend_request(friend_request_schema) + .await + .unwrap(); let relationships = user.get_mutual_relationships(other_user_id).await.unwrap(); println!("{:?}", relationships); common::teardown(bundle).await From 47246cabad00ab2d9d571c0672a27973c3c227ff Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Fri, 4 Aug 2023 15:33:46 +0200 Subject: [PATCH 040/237] Re-add derives to structs where possible --- src/types/entities/application.rs | 6 +++--- src/types/entities/attachment.rs | 2 +- src/types/entities/channel.rs | 6 +++--- src/types/entities/guild.rs | 6 +++--- src/types/entities/invite.rs | 2 +- src/types/entities/message.rs | 26 +++++++++++++------------- src/types/entities/role.rs | 2 +- src/types/entities/security_key.rs | 2 +- src/types/entities/sticker.rs | 2 +- src/types/entities/user.rs | 6 +++--- src/types/entities/user_settings.rs | 8 ++++---- src/types/schema/channel.rs | 4 ++-- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/types/entities/application.rs b/src/types/entities/application.rs index ec3c7fb..ad48ab4 100644 --- a/src/types/entities/application.rs +++ b/src/types/entities/application.rs @@ -96,7 +96,7 @@ impl Application { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] /// # Reference /// See pub struct InstallParams { @@ -157,7 +157,7 @@ pub struct ApplicationCommandOption { pub options: Arc>>, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ApplicationCommandOptionChoice { pub name: String, pub value: Value, @@ -209,7 +209,7 @@ pub struct GuildApplicationCommandPermissions { pub permissions: Vec>>, } -#[derive(Debug, Default, Clone, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] /// See pub struct ApplicationCommandPermission { pub id: Snowflake, diff --git a/src/types/entities/attachment.rs b/src/types/entities/attachment.rs index 8dce564..75ec860 100644 --- a/src/types/entities/attachment.rs +++ b/src/types/entities/attachment.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 0e66ed3..61754f0 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -122,7 +122,7 @@ pub struct Tag { pub emoji_name: Option, } -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd)] pub struct PermissionOverwrite { pub id: Snowflake, #[serde(rename = "type")] @@ -136,7 +136,7 @@ pub struct PermissionOverwrite { pub deny: String, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] /// # Reference /// See pub struct ThreadMetadata { @@ -159,7 +159,7 @@ pub struct ThreadMember { pub member: Option>>, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] /// Specifies the emoji to use as the default way to react to a [ChannelType::GuildForum] or [ChannelType::GuildMedia] channel post. /// /// # Reference diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index ae59e49..651884f 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -93,7 +93,7 @@ pub struct Guild { } /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildBan { pub user_id: Snowflake, @@ -124,13 +124,13 @@ pub struct GuildInvite { pub vanity_url: Option, } -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] pub struct UnavailableGuild { id: Snowflake, unavailable: bool, } -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] pub struct GuildCreateResponse { pub id: Snowflake, } diff --git a/src/types/entities/invite.rs b/src/types/entities/invite.rs index fe2444d..7eefd98 100644 --- a/src/types/entities/invite.rs +++ b/src/types/entities/invite.rs @@ -58,7 +58,7 @@ pub struct InviteGuild { /// See for an explanation on what /// the levels mean. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum NSFWLevel { Default = 0, diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 34a39c7..f104f97 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -67,7 +67,7 @@ pub struct Message { pub role_subscription_data: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] /// # Reference /// See pub struct MessageReference { @@ -87,7 +87,7 @@ pub struct MessageInteraction { pub member: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct AllowedMention { parse: Vec, roles: Vec, @@ -95,7 +95,7 @@ pub struct AllowedMention { replied_user: bool, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum AllowedMentionType { Roles, @@ -103,7 +103,7 @@ pub enum AllowedMentionType { Everyone, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ChannelMention { pub id: Snowflake, pub guild_id: Snowflake, @@ -130,14 +130,14 @@ pub struct Embed { fields: Option>, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct EmbedFooter { text: String, icon_url: Option, proxy_icon_url: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct EmbedImage { url: String, proxy_url: String, @@ -145,7 +145,7 @@ pub struct EmbedImage { width: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct EmbedThumbnail { url: String, proxy_url: Option, @@ -153,7 +153,7 @@ pub struct EmbedThumbnail { width: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] struct EmbedVideo { url: Option, proxy_url: Option, @@ -161,13 +161,13 @@ struct EmbedVideo { width: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct EmbedProvider { name: Option, url: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct EmbedAuthor { name: String, url: Option, @@ -175,7 +175,7 @@ pub struct EmbedAuthor { proxy_icon_url: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct EmbedField { name: String, value: String, @@ -192,7 +192,7 @@ pub struct Reaction { pub emoji: Emoji, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] pub enum Component { ActionRow = 1, Button = 2, @@ -204,7 +204,7 @@ pub enum Component { ChannelSelect = 8, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] /// # Reference /// See pub struct MessageActivity { diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 3f74218..3ad53ce 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -26,7 +26,7 @@ pub struct RoleObject { pub tags: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct RoleSubscriptionData { pub role_subscription_listing_id: Snowflake, pub tier_name: String, diff --git a/src/types/entities/security_key.rs b/src/types/entities/security_key.rs index 9ffbafa..2cf8f66 100644 --- a/src/types/entities/security_key.rs +++ b/src/types/entities/security_key.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct SecurityKey { pub id: String, diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index cdc1202..42edb7f 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -28,7 +28,7 @@ pub struct Sticker { pub sort_value: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] /// A partial sticker object. /// /// Represents the smallest amount of data required to render a sticker. diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 0adb363..5b31b6d 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -3,7 +3,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; -#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] pub struct UserData { pub valid_tokens_since: DateTime, @@ -15,7 +15,7 @@ impl User { PublicUser::from(self) } } -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct User { pub id: Snowflake, @@ -50,7 +50,7 @@ pub struct User { pub disabled: Option, } -#[derive(Debug, Default, Clone, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct PublicUser { pub id: Snowflake, pub username: Option, diff --git a/src/types/entities/user_settings.rs b/src/types/entities/user_settings.rs index 758762b..4705a92 100644 --- a/src/types/entities/user_settings.rs +++ b/src/types/entities/user_settings.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex}; use chrono::{serde::ts_milliseconds_option, Utc}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "lowercase")] pub enum UserStatus { @@ -21,7 +21,7 @@ impl std::fmt::Display for UserStatus { } } -#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "lowercase")] pub enum UserTheme { @@ -119,7 +119,7 @@ impl Default for UserSettings { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct CustomStatus { pub emoji_id: Option, @@ -129,7 +129,7 @@ pub struct CustomStatus { pub text: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct FriendSourceFlags { pub all: bool, } diff --git a/src/types/schema/channel.rs b/src/types/schema/channel.rs index e7261cb..27c78ee 100644 --- a/src/types/schema/channel.rs +++ b/src/types/schema/channel.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::PermissionOverwrite, Snowflake}; -#[derive(Debug, Deserialize, Serialize, Default)] +#[derive(Debug, Deserialize, Serialize, Default, PartialEq, PartialOrd)] #[serde(rename_all = "snake_case")] pub struct ChannelCreateSchema { pub name: String, @@ -27,7 +27,7 @@ pub struct ChannelCreateSchema { pub video_quality_mode: Option, } -#[derive(Debug, Deserialize, Serialize, Clone, Default)] +#[derive(Debug, Deserialize, Serialize, Clone, Default, PartialEq, PartialOrd)] #[serde(rename_all = "snake_case")] pub struct ChannelModifySchema { pub name: Option, From 6bed0badc892b94d96ea6bc6cf7b27094131253b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 16:41:37 +0200 Subject: [PATCH 041/237] Add JsonField derive --- chorus-macros/src/lib.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index c8d5e87..3a9397d 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -16,3 +16,22 @@ pub fn updateable_macro_derive(input: TokenStream) -> TokenStream { } .into() } + +#[proc_macro_derive(JsonField)] +pub fn jsonfield_macro_derive(input: TokenStream) -> TokenStream { + let ast: syn::DeriveInput = syn::parse(input).unwrap(); + + let name = &ast.ident; + // No need for macro hygiene, we're only using this in chorus + quote! { + impl JsonField for #name { + fn get_json(&self) -> String { + self.json.clone() + } + fn set_json(&mut self, json: String) { + self.json = json; + } + } + } + .into() +} From b9b5e5e463cc38a06ba0e164fba2bf76e3b84897 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 16:41:51 +0200 Subject: [PATCH 042/237] Add update_object --- src/types/events/mod.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index d477800..fd152ab 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -1,3 +1,6 @@ +use std::collections::HashMap; + +use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; pub use application::*; @@ -19,6 +22,7 @@ pub use ready::*; pub use relationship::*; pub use request_members::*; pub use resume::*; +use serde_json::{from_str, from_value, to_value, Value}; pub use session::*; pub use stage_instance::*; pub use thread::*; @@ -109,10 +113,31 @@ impl<'a> WebSocketEvent for GatewayReceivePayload<'a> {} /// This would imply, that the [`WebSocketEvent`] "[`ChannelUpdate`]" contains new/updated information /// about a [`Channel`]. The update method describes how this new information will be turned into /// a [`Channel`] object. -pub(crate) trait UpdateMessage: Clone +pub(crate) trait UpdateMessage: Clone + JsonField where - T: Updateable, + T: Updateable + Serialize + DeserializeOwned, { - fn update(&self, object_to_update: &mut T); + fn update(&mut self, object_to_update: &mut T) { + update_object(self.get_json(), object_to_update) + } fn id(&self) -> Snowflake; } + +pub(crate) trait JsonField: Clone { + fn set_json(&mut self, json: String); + fn get_json(&self) -> String; +} + +/// Only applicable for events where the Update struct is the same as the Entity struct +pub(crate) fn update_object( + value: String, + object: &mut (impl Updateable + Serialize + DeserializeOwned + Clone), +) { + let data_from_event: HashMap = from_str(&value).unwrap(); + let mut original_data: HashMap = + from_value(to_value(object.clone()).unwrap()).unwrap(); + for (updated_entry_key, updated_entry_value) in data_from_event.into_iter() { + original_data.insert(updated_entry_key.clone(), updated_entry_value); + } + *object = from_value(to_value(original_data).unwrap()).unwrap(); +} From cfb84f3da069d6f190d6dd9551150cf4e2d3da4a Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 16:41:57 +0200 Subject: [PATCH 043/237] Fix channel.rs --- src/types/events/channel.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 002230c..41ab288 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -1,5 +1,6 @@ use crate::types::events::WebSocketEvent; -use crate::types::{entities::Channel, Snowflake}; +use crate::types::{entities::Channel, JsonField, Snowflake}; +use chorus_macros::JsonField; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -24,17 +25,19 @@ pub struct ChannelCreate { impl WebSocketEvent for ChannelCreate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct ChannelUpdate { #[serde(flatten)] pub channel: Channel, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for ChannelUpdate {} impl UpdateMessage for ChannelUpdate { - fn update(&self, object_to_update: &mut Channel) { + fn update(&mut self, object_to_update: &mut Channel) { *object_to_update = self.channel.clone(); } fn id(&self) -> Snowflake { From 7b05d391b0bb65be22b86871bc57f6bd8fdb0fce Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 16:46:15 +0200 Subject: [PATCH 044/237] Add clone bound to T --- src/types/events/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index fd152ab..ca310b9 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -115,7 +115,7 @@ impl<'a> WebSocketEvent for GatewayReceivePayload<'a> {} /// a [`Channel`] object. pub(crate) trait UpdateMessage: Clone + JsonField where - T: Updateable + Serialize + DeserializeOwned, + T: Updateable + Serialize + DeserializeOwned + Clone, { fn update(&mut self, object_to_update: &mut T) { update_object(self.get_json(), object_to_update) From 8f57150a79b097f26dae14b0edce87459aa73ff9 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 16:46:22 +0200 Subject: [PATCH 045/237] Make message mut --- src/gateway.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gateway.rs b/src/gateway.rs index eaac29f..ea5b203 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -476,7 +476,7 @@ impl Gateway { Err(err) => warn!("Failed to parse gateway event {event_name} ({err})"), Ok(message) => { $( - let message: $message_type = message; + let mut message: $message_type = message; if let Some(to_update) = self.store.lock().await.get(&message.id()) { if let Some((tx, _)) = to_update.downcast_ref::<(watch::Sender<$update_type>, watch::Receiver<$update_type>)>() { tx.send_modify(|object| message.update(object)); From c8abec768629006bfccacd2e409d04b090839925 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 16:54:03 +0200 Subject: [PATCH 046/237] Add note about GatewayHandle: `store` --- src/gateway.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gateway.rs b/src/gateway.rs index ea5b203..a3d0d1b 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -152,6 +152,10 @@ impl GatewayMessage { /// [`GatewayEvents`](GatewayEvent), which you can subscribe to. Gateway events include all currently /// implemented types with the trait [`WebSocketEvent`] /// Using this handle you can also send Gateway Events directly. +/// +/// # Store +/// The value of `store`s [`HashMap`] is a [`tokio::sync::watch::channel`]. See the +/// [`Updateable`] trait for more information. #[derive(Debug)] pub struct GatewayHandle { pub url: String, From 55a2335664094002918ad504d965a67578f2a83e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 16:54:56 +0200 Subject: [PATCH 047/237] Add note about Gateway: store --- src/gateway.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gateway.rs b/src/gateway.rs index a3d0d1b..58a2bdd 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -297,6 +297,8 @@ impl GatewayHandle { } } +/// The value of `store`s [`HashMap`] is a [`tokio::sync::watch::channel`]. See the +/// [`Updateable`] trait for more information. pub struct Gateway { events: Arc>, heartbeat_handler: HeartbeatHandler, From a2561fd2e09eecd2a36bb8bd56fa787c78750b9c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 17:57:03 +0200 Subject: [PATCH 048/237] Change Arc> components to Arc> --- src/api/auth/login.rs | 2 +- src/api/auth/register.rs | 2 +- src/api/users/users.rs | 2 +- src/instance.rs | 14 +++++++------- src/types/entities/application.rs | 16 ++++++++-------- src/types/entities/audit_log.rs | 4 ++-- src/types/entities/auto_moderation.rs | 8 ++++---- src/types/entities/channel.rs | 10 +++++----- src/types/entities/emoji.rs | 4 ++-- src/types/entities/guild.rs | 24 ++++++++++++------------ src/types/entities/guild_member.rs | 4 ++-- src/types/entities/integration.rs | 6 +++--- src/types/entities/invite.rs | 4 ++-- src/types/entities/relationship.rs | 4 ++-- src/types/entities/sticker.rs | 4 ++-- src/types/entities/team.rs | 4 ++-- src/types/entities/template.rs | 8 ++++---- src/types/entities/user_settings.rs | 8 ++++---- src/types/entities/voice_state.rs | 4 ++-- src/types/entities/webhook.rs | 6 +++--- 20 files changed, 69 insertions(+), 69 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 447e4c0..311c90b 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -1,6 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use reqwest::Client; use serde_json::to_string; diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index ea74f29..634c92f 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use std::{cell::RefCell, rc::Rc}; use reqwest::Client; diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 03af2f9..8113701 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use std::{cell::RefCell, rc::Rc}; use reqwest::Client; diff --git a/src/instance.rs b/src/instance.rs index 5c2e98b..4ed0f60 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::fmt; use std::rc::Rc; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use reqwest::Client; use serde::{Deserialize, Serialize}; @@ -91,8 +91,8 @@ pub struct UserMeta { pub belongs_to: Rc>, pub token: String, pub limits: Option>, - pub settings: Arc>, - pub object: Arc>, + pub settings: Arc>, + pub object: Arc>, pub gateway: GatewayHandle, } @@ -114,8 +114,8 @@ impl UserMeta { belongs_to: Rc>, token: String, limits: Option>, - settings: Arc>, - object: Arc>, + settings: Arc>, + object: Arc>, gateway: GatewayHandle, ) -> UserMeta { UserMeta { @@ -134,8 +134,8 @@ impl UserMeta { /// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify /// first. pub(crate) async fn shell(instance: Rc>, token: String) -> UserMeta { - let settings = Arc::new(Mutex::new(UserSettings::default())); - let object = Arc::new(Mutex::new(User::default())); + let settings = Arc::new(RwLock::new(UserSettings::default())); + let object = Arc::new(RwLock::new(User::default())); let wss_url = instance.borrow().urls.wss.clone(); // Dummy gateway object let gateway = Gateway::new(wss_url).await.unwrap(); diff --git a/src/types/entities/application.rs b/src/types/entities/application.rs index ad48ab4..0b55626 100644 --- a/src/types/entities/application.rs +++ b/src/types/entities/application.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use bitflags::bitflags; use serde::{Deserialize, Serialize}; @@ -27,7 +27,7 @@ pub struct Application { pub bot_require_code_grant: bool, pub verify_key: String, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub owner: Arc>, + pub owner: Arc>, pub flags: u64, #[cfg(feature = "sqlx")] pub redirect_uris: Option>>, @@ -49,7 +49,7 @@ pub struct Application { #[cfg(feature = "sqlx")] pub install_params: Option>, #[cfg(not(feature = "sqlx"))] - pub install_params: Option>>, + pub install_params: Option>>, pub terms_of_service_url: Option, pub privacy_policy_url: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] @@ -142,7 +142,7 @@ pub struct ApplicationCommand { pub application_id: Snowflake, pub name: String, pub description: String, - pub options: Vec>>, + pub options: Vec>>, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -154,7 +154,7 @@ pub struct ApplicationCommandOption { pub description: String, pub required: bool, pub choices: Vec, - pub options: Arc>>, + pub options: Arc>>, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -190,14 +190,14 @@ pub enum ApplicationCommandOptionType { pub struct ApplicationCommandInteractionData { pub id: Snowflake, pub name: String, - pub options: Vec>>, + pub options: Vec>>, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationCommandInteractionDataOption { pub name: String, pub value: Value, - pub options: Vec>>, + pub options: Vec>>, } #[derive(Debug, Default, Clone, Serialize, Deserialize)] @@ -206,7 +206,7 @@ pub struct GuildApplicationCommandPermissions { pub id: Snowflake, pub application_id: Snowflake, pub guild_id: Snowflake, - pub permissions: Vec>>, + pub permissions: Vec>>, } #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] diff --git a/src/types/entities/audit_log.rs b/src/types/entities/audit_log.rs index e0d05e3..be14f0f 100644 --- a/src/types/entities/audit_log.rs +++ b/src/types/entities/audit_log.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -8,7 +8,7 @@ use crate::types::utils::Snowflake; /// See pub struct AuditLogEntry { pub target_id: Option, - pub changes: Option>>>, + pub changes: Option>>>, pub user_id: Option, pub id: Snowflake, // to:do implement an enum for these types diff --git a/src/types/entities/auto_moderation.rs b/src/types/entities/auto_moderation.rs index afb1ec6..77f4fa2 100644 --- a/src/types/entities/auto_moderation.rs +++ b/src/types/entities/auto_moderation.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -14,8 +14,8 @@ pub struct AutoModerationRule { pub creator_id: Snowflake, pub event_type: AutoModerationRuleEventType, pub trigger_type: AutoModerationRuleTriggerType, - pub trigger_metadata: Arc>, - pub actions: Vec>>, + pub trigger_metadata: Arc>, + pub actions: Vec>>, pub enabled: bool, pub exempt_roles: Vec, pub exempt_channels: Vec, @@ -92,7 +92,7 @@ pub enum AutoModerationRuleKeywordPresetType { pub struct AutoModerationAction { #[serde(rename = "type")] pub action_type: AutoModerationActionType, - pub metadata: Option>>, + pub metadata: Option>>, } #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 61754f0..96cf557 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chorus_macros::Updateable; use chrono::Utc; @@ -48,7 +48,7 @@ pub struct Channel { pub last_pin_timestamp: Option, pub managed: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub member: Option>>, + pub member: Option>>, pub member_count: Option, pub message_count: Option, pub name: Option, @@ -58,12 +58,12 @@ pub struct Channel { #[cfg(feature = "sqlx")] pub permission_overwrites: Option>>, #[cfg(not(feature = "sqlx"))] - pub permission_overwrites: Option>>>, + pub permission_overwrites: Option>>>, pub permissions: Option, pub position: Option, pub rate_limit_per_user: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub recipients: Option>>>, + pub recipients: Option>>>, pub rtc_region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub thread_metadata: Option, @@ -156,7 +156,7 @@ pub struct ThreadMember { pub user_id: Option, pub join_timestamp: Option, pub flags: Option, - pub member: Option>>, + pub member: Option>>, } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 38d7da7..f96b2b5 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -17,7 +17,7 @@ pub struct Emoji { #[cfg(not(feature = "sqlx"))] pub roles: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, pub require_colons: Option, pub managed: Option, pub animated: Option, diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 651884f..b95b68a 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -27,13 +27,13 @@ pub struct Guild { #[cfg_attr(feature = "sqlx", sqlx(skip))] pub bans: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub channels: Option>>>, + pub channels: Option>>>, pub default_message_notifications: Option, pub description: Option, pub discovery_splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] #[serde(default)] - pub emojis: Vec>>, + pub emojis: Vec>>, pub explicit_content_filter: Option, //#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))] pub features: Option, @@ -42,7 +42,7 @@ pub struct Guild { pub icon_hash: Option, pub id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub invites: Option>>>, + pub invites: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub joined_at: Option, pub large: Option, @@ -68,7 +68,7 @@ pub struct Guild { pub public_updates_channel_id: Option, pub region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub roles: Option>>>, + pub roles: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub rules_channel: Option, pub rules_channel_id: Option, @@ -81,13 +81,13 @@ pub struct Guild { pub vanity_url_code: Option, pub verification_level: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub voice_states: Option>>>, + pub voice_states: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub webhooks: Option>>>, + pub webhooks: Option>>>, #[cfg(feature = "sqlx")] pub welcome_screen: Option>, #[cfg(not(feature = "sqlx"))] - pub welcome_screen: Option>>, + pub welcome_screen: Option>>, pub widget_channel_id: Option, pub widget_enabled: Option, } @@ -113,11 +113,11 @@ pub struct GuildInvite { pub created_at: DateTime, pub expires_at: Option>, pub guild_id: Snowflake, - pub guild: Option>>, + pub guild: Option>>, pub channel_id: Snowflake, - pub channel: Option>>, + pub channel: Option>>, pub inviter_id: Option, - pub inviter: Option>>, + pub inviter: Option>>, pub target_user_id: Option, pub target_user: Option, pub target_user_type: Option, @@ -151,7 +151,7 @@ pub struct GuildScheduledEvent { pub entity_type: GuildScheduledEventEntityType, pub entity_id: Option, pub entity_metadata: Option, - pub creator: Option>>, + pub creator: Option>>, pub user_count: Option, pub image: Option, } diff --git a/src/types/entities/guild_member.rs b/src/types/entities/guild_member.rs index af63cfb..bf2f93b 100644 --- a/src/types/entities/guild_member.rs +++ b/src/types/entities/guild_member.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -10,7 +10,7 @@ use crate::types::{entities::PublicUser, Snowflake}; /// # Reference /// See pub struct GuildMember { - pub user: Option>>, + pub user: Option>>, pub nick: Option, pub avatar: Option, pub roles: Vec, diff --git a/src/types/entities/integration.rs b/src/types/entities/integration.rs index a95c33c..0913213 100644 --- a/src/types/entities/integration.rs +++ b/src/types/entities/integration.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -23,14 +23,14 @@ pub struct Integration { pub expire_behaviour: Option, pub expire_grace_period: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub account: IntegrationAccount, pub synced_at: Option>, pub subscriber_count: Option, pub revoked: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub application: Option>>, + pub application: Option>>, pub scopes: Option>, } diff --git a/src/types/entities/invite.rs b/src/types/entities/invite.rs index 7eefd98..1e6befc 100644 --- a/src/types/entities/invite.rs +++ b/src/types/entities/invite.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -70,7 +70,7 @@ pub enum NSFWLevel { /// See #[derive(Debug, Serialize, Deserialize)] pub struct InviteStageInstance { - pub members: Vec>>, + pub members: Vec>>, pub participant_count: i32, pub speaker_count: i32, pub topic: String, diff --git a/src/types/entities/relationship.rs b/src/types/entities/relationship.rs index a5f5bcb..576d99a 100644 --- a/src/types/entities/relationship.rs +++ b/src/types/entities/relationship.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -15,7 +15,7 @@ pub struct Relationship { #[serde(rename = "type")] pub relationship_type: RelationshipType, pub nickname: Option, - pub user: Arc>, + pub user: Arc>, pub since: Option>, } diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index 42edb7f..5413112 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -24,7 +24,7 @@ pub struct Sticker { pub available: Option, pub guild_id: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, pub sort_value: Option, } diff --git a/src/types/entities/team.rs b/src/types/entities/team.rs index fe6562b..8e32f55 100644 --- a/src/types/entities/team.rs +++ b/src/types/entities/team.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -21,5 +21,5 @@ pub struct TeamMember { pub membership_state: u8, pub permissions: Vec, pub team_id: Snowflake, - pub user: Arc>, + pub user: Arc>, } diff --git a/src/types/entities/template.rs b/src/types/entities/template.rs index 0550e9e..1305a98 100644 --- a/src/types/entities/template.rs +++ b/src/types/entities/template.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -18,13 +18,13 @@ pub struct GuildTemplate { pub usage_count: Option, pub creator_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub creator: Arc>, + pub creator: Arc>, pub created_at: DateTime, pub updated_at: DateTime, pub source_guild_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub source_guild: Vec>>, + pub source_guild: Vec>>, // Unsure how a {recursive: Guild} looks like, might be a Vec? #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub serialized_source_guild: Vec>>, + pub serialized_source_guild: Vec>>, } diff --git a/src/types/entities/user_settings.rs b/src/types/entities/user_settings.rs index 4705a92..1be2c0a 100644 --- a/src/types/entities/user_settings.rs +++ b/src/types/entities/user_settings.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{serde::ts_milliseconds_option, Utc}; use serde::{Deserialize, Serialize}; @@ -75,7 +75,7 @@ pub struct UserSettings { #[cfg(not(feature = "sqlx"))] pub restricted_guilds: Vec, pub show_current_game: bool, - pub status: Arc>, + pub status: Arc>, pub stream_notifications_enabled: bool, pub theme: UserTheme, pub timezone_offset: i16, @@ -111,7 +111,7 @@ impl Default for UserSettings { render_reactions: true, restricted_guilds: Default::default(), show_current_game: true, - status: Arc::new(Mutex::new(UserStatus::Online)), + status: Arc::new(RwLock::new(UserStatus::Online)), stream_notifications_enabled: false, theme: UserTheme::Dark, timezone_offset: 0, @@ -151,5 +151,5 @@ pub struct GuildFolder { #[derive(Debug, Serialize, Deserialize)] pub struct LoginResult { pub token: String, - pub settings: Arc>, + pub settings: Arc>, } diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index 29b8e6e..9f6a2c0 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -16,7 +16,7 @@ pub struct VoiceState { pub guild: Option, pub channel_id: Option, pub user_id: Snowflake, - pub member: Option>>, + pub member: Option>>, pub session_id: Snowflake, pub token: Option, pub deaf: bool, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index f8b6530..079f584 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -22,10 +22,10 @@ pub struct Webhook { pub application_id: Snowflake, #[serde(skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, #[serde(skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub source_guild: Option>>, + pub source_guild: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub url: Option, } From dad419c1dec1b23c445474f1e4ff5afcc410bffb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 4 Aug 2023 20:08:49 +0200 Subject: [PATCH 049/237] update mutex to rwlock --- src/api/auth/login.rs | 2 +- src/api/auth/register.rs | 4 ++-- src/api/channels/channels.rs | 1 - src/api/users/users.rs | 2 +- tests/channels.rs | 24 ++++++++++++------------ tests/members.rs | 2 +- tests/relationships.rs | 24 ++++++++++++------------ 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 311c90b..3b3ffc6 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -46,7 +46,7 @@ impl Instance { login_result.token, self.clone_limits_if_some(), login_result.settings, - Arc::new(Mutex::new(object)), + Arc::new(RwLock::new(object)), gateway, ); Ok(user) diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 634c92f..7beaa76 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -52,8 +52,8 @@ impl Instance { Rc::new(RefCell::new(self.clone())), token.clone(), self.clone_limits_if_some(), - Arc::new(Mutex::new(settings)), - Arc::new(Mutex::new(user_object)), + Arc::new(RwLock::new(settings)), + Arc::new(RwLock::new(user_object)), gateway, ); Ok(user) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index bf2c48c..08200d1 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -62,7 +62,6 @@ impl Channel { /// # Reference /// See pub async fn modify( - &self, modify_data: ChannelModifySchema, channel_id: Snowflake, user: &mut UserMeta, diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 8113701..33afbee 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -60,7 +60,7 @@ impl UserMeta { .deserialize_response::(self) .await .unwrap(); - self.object = Arc::new(Mutex::new(user_updated.clone())); + self.object = Arc::new(RwLock::new(user_updated.clone())); Ok(user_updated) } diff --git a/tests/channels.rs b/tests/channels.rs index d810c10..2fc1fc3 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -50,7 +50,7 @@ async fn modify_channel() { default_thread_rate_limit_per_user: None, video_quality_mode: None, }; - let modified_channel = Channel::modify(channel, modify_data, channel.id, &mut bundle.user) + let modified_channel = Channel::modify(modify_data, channel.id, &mut bundle.user) .await .unwrap(); assert_eq!(modified_channel.name, Some(CHANNEL_NAME.to_string())); @@ -59,7 +59,7 @@ async fn modify_channel() { PermissionFlags::MANAGE_CHANNELS, PermissionFlags::MANAGE_MESSAGES, ])); - let user_id: types::Snowflake = bundle.user.object.lock().unwrap().id; + let user_id: types::Snowflake = bundle.user.object.read().unwrap().id; let permission_override = PermissionOverwrite { id: user_id, overwrite_type: "1".to_string(), @@ -144,7 +144,7 @@ async fn create_dm() { let other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { - recipients: Some(Vec::from([other_user.object.lock().unwrap().id])), + recipients: Some(Vec::from([other_user.object.read().unwrap().id])), access_tokens: None, nicks: None, }; @@ -160,11 +160,11 @@ async fn create_dm() { .unwrap() .get(0) .unwrap() - .lock() + .read() .unwrap() .id .clone(), - other_user.object.lock().unwrap().id + other_user.object.read().unwrap().id ); assert_eq!( dm_channel @@ -173,11 +173,11 @@ async fn create_dm() { .unwrap() .get(1) .unwrap() - .lock() + .read() .unwrap() .id .clone(), - user.object.lock().unwrap().id.clone() + user.object.read().unwrap().id.clone() ); common::teardown(bundle).await; } @@ -189,9 +189,9 @@ async fn remove_add_person_from_to_dm() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let mut third_user = bundle.create_user("integrationtestuser3").await; - let third_user_id = third_user.object.lock().unwrap().id; - let other_user_id = other_user.object.lock().unwrap().id; - let user_id = bundle.user.object.lock().unwrap().id; + let third_user_id = third_user.object.read().unwrap().id; + let other_user_id = other_user.object.read().unwrap().id; + let user_id = bundle.user.object.read().unwrap().id; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { recipients: Some(Vec::from([other_user_id, third_user_id])), @@ -234,7 +234,7 @@ async fn remove_add_person_from_to_dm() { .unwrap() .get(0) .unwrap() - .lock() + .read() .unwrap() .id, other_user_id @@ -246,7 +246,7 @@ async fn remove_add_person_from_to_dm() { .unwrap() .get(1) .unwrap() - .lock() + .read() .unwrap() .id, user_id diff --git a/tests/members.rs b/tests/members.rs index a314be7..aae8db0 100644 --- a/tests/members.rs +++ b/tests/members.rs @@ -7,7 +7,7 @@ async fn add_remove_role() -> ChorusResult<()> { let mut bundle = common::setup().await; let guild = bundle.guild.id; let role = bundle.role.id; - let member_id = bundle.user.object.lock().unwrap().id; + let member_id = bundle.user.object.read().unwrap().id; GuildMember::add_role(&mut bundle.user, guild, member_id, role).await?; let member = GuildMember::get(&mut bundle.user, guild, member_id) .await diff --git a/tests/relationships.rs b/tests/relationships.rs index 2773474..09ddab0 100644 --- a/tests/relationships.rs +++ b/tests/relationships.rs @@ -7,9 +7,9 @@ async fn test_get_mutual_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let username = user.object.lock().unwrap().username.clone(); - let discriminator = user.object.lock().unwrap().discriminator.clone(); - let other_user_id: types::Snowflake = other_user.object.lock().unwrap().id; + let username = user.object.read().unwrap().username.clone(); + let discriminator = user.object.read().unwrap().discriminator.clone(); + let other_user_id: types::Snowflake = other_user.object.read().unwrap().id; let friend_request_schema = types::FriendRequestSendSchema { username, discriminator: Some(discriminator), @@ -28,8 +28,8 @@ async fn test_get_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let username = user.object.lock().unwrap().username.clone(); - let discriminator = user.object.lock().unwrap().discriminator.clone(); + let username = user.object.read().unwrap().username.clone(); + let discriminator = user.object.read().unwrap().discriminator.clone(); let friend_request_schema = types::FriendRequestSendSchema { username, discriminator: Some(discriminator), @@ -41,7 +41,7 @@ async fn test_get_relationships() { let relationships = user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - other_user.object.lock().unwrap().id + other_user.object.read().unwrap().id ); common::teardown(bundle).await } @@ -51,8 +51,8 @@ async fn test_modify_relationship_friends() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let user_id: types::Snowflake = user.object.lock().unwrap().id; - let other_user_id: types::Snowflake = other_user.object.lock().unwrap().id; + let user_id: types::Snowflake = user.object.read().unwrap().id; + let other_user_id: types::Snowflake = other_user.object.read().unwrap().id; other_user .modify_user_relationship(user_id, types::RelationshipType::Friends) @@ -61,7 +61,7 @@ async fn test_modify_relationship_friends() { let relationships = user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - other_user.object.lock().unwrap().id + other_user.object.read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, @@ -70,7 +70,7 @@ async fn test_modify_relationship_friends() { let relationships = other_user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - user.object.lock().unwrap().id + user.object.read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, @@ -102,7 +102,7 @@ async fn test_modify_relationship_block() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let user_id: types::Snowflake = user.object.lock().unwrap().id; + let user_id: types::Snowflake = user.object.read().unwrap().id; other_user .modify_user_relationship(user_id, types::RelationshipType::Blocked) @@ -113,7 +113,7 @@ async fn test_modify_relationship_block() { let relationships = other_user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - user.object.lock().unwrap().id + user.object.read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, From 1cc29540d000179d5df4ff31bb5a6f338924304d Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:15:23 +0000 Subject: [PATCH 050/237] Minor improvements to message events (#177) --- src/types/events/message.rs | 84 ++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/src/types/events/message.rs b/src/types/events/message.rs index 70f28f6..fac083b 100644 --- a/src/types/events/message.rs +++ b/src/types/events/message.rs @@ -8,6 +8,8 @@ use crate::types::{ use super::WebSocketEvent; #[derive(Debug, Deserialize, Serialize, Default, Clone)] +/// # Reference +/// See pub struct TypingStartEvent { pub channel_id: Snowflake, pub guild_id: Option, @@ -22,89 +24,103 @@ impl WebSocketEvent for TypingStartEvent {} /// See pub struct MessageCreate { #[serde(flatten)] - message: Message, - guild_id: Option, - member: Option, - mentions: Option>, + pub message: Message, + pub guild_id: Option, + pub member: Option, + pub mentions: Option>, } #[derive(Debug, Serialize, Deserialize, Default, Clone)] /// See pub struct MessageCreateUser { #[serde(flatten)] - user: PublicUser, - member: Option, + pub user: PublicUser, + pub member: Option, } impl WebSocketEvent for MessageCreate {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] +/// # Reference +/// See pub struct MessageUpdate { #[serde(flatten)] - message: Message, - guild_id: Option, - member: Option, - mentions: Option>, + pub message: Message, + pub guild_id: Option, + pub member: Option, + pub mentions: Option>, } impl WebSocketEvent for MessageUpdate {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] +/// # Reference +/// See pub struct MessageDelete { - id: Snowflake, - channel_id: Snowflake, - guild_id: Option, + pub id: Snowflake, + pub channel_id: Snowflake, + pub guild_id: Option, } impl WebSocketEvent for MessageDelete {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] +/// # Reference +/// See pub struct MessageDeleteBulk { - ids: Vec, - channel_id: Snowflake, - guild_id: Option, + pub ids: Vec, + pub channel_id: Snowflake, + pub guild_id: Option, } impl WebSocketEvent for MessageDeleteBulk {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] +/// # Reference +/// See pub struct MessageReactionAdd { - user_id: Snowflake, - channel_id: Snowflake, - message_id: Snowflake, - guild_id: Option, - member: Option, - emoji: Emoji, + pub user_id: Snowflake, + pub channel_id: Snowflake, + pub message_id: Snowflake, + pub guild_id: Option, + pub member: Option, + pub emoji: Emoji, } impl WebSocketEvent for MessageReactionAdd {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] +/// # Reference +/// See pub struct MessageReactionRemove { - user_id: Snowflake, - channel_id: Snowflake, - message_id: Snowflake, - guild_id: Option, - emoji: Emoji, + pub user_id: Snowflake, + pub channel_id: Snowflake, + pub message_id: Snowflake, + pub guild_id: Option, + pub emoji: Emoji, } impl WebSocketEvent for MessageReactionRemove {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] +/// # Reference +/// See pub struct MessageReactionRemoveAll { - channel_id: Snowflake, - message_id: Snowflake, - guild_id: Option, + pub channel_id: Snowflake, + pub message_id: Snowflake, + pub guild_id: Option, } impl WebSocketEvent for MessageReactionRemoveAll {} #[derive(Debug, Serialize, Deserialize, Default, Clone)] +/// # Reference +/// See pub struct MessageReactionRemoveEmoji { - channel_id: Snowflake, - message_id: Snowflake, - guild_id: Option, - emoji: Emoji, + pub channel_id: Snowflake, + pub message_id: Snowflake, + pub guild_id: Option, + pub emoji: Emoji, } impl WebSocketEvent for MessageReactionRemoveEmoji {} From 07818b2cd6b4a0f83fc9d577936de02281f9c766 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 7 Aug 2023 14:56:10 +0200 Subject: [PATCH 051/237] Fix unwrap panic on trying to access rate limits --- src/ratelimiter.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 0389ad3..2c1ecd0 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -237,6 +237,9 @@ impl ChorusRequest { /// reset to the rate limit limit. /// 2. The remaining rate limit is decreased by 1. fn update_rate_limits(user: &mut UserMeta, limit_type: &LimitType, response_was_err: bool) { + if user.belongs_to.borrow().limits_information.is_none() { + return; + } let instance_dictated_limits = [ &LimitType::AuthLogin, &LimitType::AuthRegister, From 1801d22273b9dfd3b7f7f886435c5baa4e5bb0d3 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Mon, 7 Aug 2023 18:34:58 +0000 Subject: [PATCH 052/237] Minor snowflake updates (#179) * Make snowflake fully public * Simple into for snowflake --- src/types/utils/snowflake.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/types/utils/snowflake.rs b/src/types/utils/snowflake.rs index a9f572b..b4e1d9e 100644 --- a/src/types/utils/snowflake.rs +++ b/src/types/utils/snowflake.rs @@ -17,7 +17,7 @@ const EPOCH: i64 = 1420070400000; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr(feature = "sqlx", derive(Type))] #[cfg_attr(feature = "sqlx", sqlx(transparent))] -pub struct Snowflake(u64); +pub struct Snowflake(pub u64); impl Snowflake { /// Generates a snowflake for the current timestamp, with worker id 0 and process id 1. @@ -53,6 +53,15 @@ impl Display for Snowflake { } } +impl From for Snowflake +where + T: Into, +{ + fn from(item: T) -> Self { + Self(item.into()) + } +} + impl serde::Serialize for Snowflake { fn serialize(&self, serializer: S) -> Result where From e0d7df417cb21940c9c448cf7f94ad1abe998676 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sat, 12 Aug 2023 14:48:33 +0000 Subject: [PATCH 053/237] Fix trailing /s (#180) --- src/api/channels/channels.rs | 10 +++++----- src/api/channels/messages.rs | 4 ++-- src/api/channels/reactions.rs | 10 +++++----- src/api/guilds/guilds.rs | 10 +++++----- src/api/guilds/member.rs | 6 +++--- src/api/guilds/roles.rs | 8 ++++---- src/api/invites/mod.rs | 6 +++--- src/api/policies/instance/instance.rs | 2 +- src/api/users/guilds.rs | 2 +- src/api/users/relationships.rs | 14 +++++++------- src/api/users/users.rs | 8 ++++---- 11 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index bf2c48c..0c6f3e3 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -19,7 +19,7 @@ impl Channel { let url = user.belongs_to.borrow().urls.api.clone(); let chorus_request = ChorusRequest { request: Client::new() - .get(format!("{}/channels/{}/", url, channel_id)) + .get(format!("{}/channels/{}", url, channel_id)) .bearer_auth(user.token()), limit_type: LimitType::Channel(channel_id), }; @@ -37,7 +37,7 @@ impl Channel { let chorus_request = ChorusRequest { request: Client::new() .delete(format!( - "{}/channels/{}/", + "{}/channels/{}", user.belongs_to.borrow().urls.api, self.id )) @@ -70,7 +70,7 @@ impl Channel { let chorus_request = ChorusRequest { request: Client::new() .patch(format!( - "{}/channels/{}/", + "{}/channels/{}", user.belongs_to.borrow().urls.api, channel_id )) @@ -124,7 +124,7 @@ impl Channel { ) -> ChorusResult<()> { let mut request = Client::new() .put(format!( - "{}/channels/{}/recipients/{}/", + "{}/channels/{}/recipients/{}", user.belongs_to.borrow().urls.api, self.id, recipient_id @@ -152,7 +152,7 @@ impl Channel { ) -> ChorusResult<()> { let request = Client::new() .delete(format!( - "{}/channels/{}/recipients/{}/", + "{}/channels/{}/recipients/{}", user.belongs_to.borrow().urls.api, self.id, recipient_id diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 5f1745b..b93ce2e 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -25,7 +25,7 @@ impl Message { if message.attachments.is_none() { let chorus_request = ChorusRequest { request: Client::new() - .post(format!("{}/channels/{}/messages/", url_api, channel_id)) + .post(format!("{}/channels/{}/messages", url_api, channel_id)) .bearer_auth(user.token()) .body(to_string(&message).unwrap()), limit_type: LimitType::Channel(channel_id), @@ -61,7 +61,7 @@ impl Message { let chorus_request = ChorusRequest { request: Client::new() - .post(format!("{}/channels/{}/messages/", url_api, channel_id)) + .post(format!("{}/channels/{}/messages", url_api, channel_id)) .bearer_auth(user.token()) .multipart(form), limit_type: LimitType::Channel(channel_id), diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index b7b221f..05fcea0 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -23,7 +23,7 @@ impl ReactionMeta { /// See pub async fn delete_all(&self, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( - "{}/channels/{}/messages/{}/reactions/", + "{}/channels/{}/messages/{}/reactions", user.belongs_to.borrow().urls.api, self.channel_id, self.message_id @@ -44,7 +44,7 @@ impl ReactionMeta { /// See pub async fn get(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult> { let url = format!( - "{}/channels/{}/messages/{}/reactions/{}/", + "{}/channels/{}/messages/{}/reactions/{}", user.belongs_to.borrow().urls.api, self.channel_id, self.message_id, @@ -70,7 +70,7 @@ impl ReactionMeta { /// See pub async fn delete_emoji(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( - "{}/channels/{}/messages/{}/reactions/{}/", + "{}/channels/{}/messages/{}/reactions/{}", user.belongs_to.borrow().urls.api, self.channel_id, self.message_id, @@ -97,7 +97,7 @@ impl ReactionMeta { /// See pub async fn create(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( - "{}/channels/{}/messages/{}/reactions/{}/@me/", + "{}/channels/{}/messages/{}/reactions/{}/@me", user.belongs_to.borrow().urls.api, self.channel_id, self.message_id, @@ -119,7 +119,7 @@ impl ReactionMeta { /// See pub async fn remove(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { let url = format!( - "{}/channels/{}/messages/{}/reactions/{}/@me/", + "{}/channels/{}/messages/{}/reactions/{}/@me", user.belongs_to.borrow().urls.api, self.channel_id, self.message_id, diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 43a8cdf..0c8b9cf 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -19,7 +19,7 @@ impl Guild { user: &mut UserMeta, guild_create_schema: GuildCreateSchema, ) -> ChorusResult { - let url = format!("{}/guilds/", user.belongs_to.borrow().urls.api); + let url = format!("{}/guilds", user.belongs_to.borrow().urls.api); let chorus_request = ChorusRequest { request: Client::new() .post(url.clone()) @@ -51,7 +51,7 @@ impl Guild { /// See pub async fn delete(user: &mut UserMeta, guild_id: Snowflake) -> ChorusResult<()> { let url = format!( - "{}/guilds/{}/delete/", + "{}/guilds/{}/delete", user.belongs_to.borrow().urls.api, guild_id ); @@ -91,7 +91,7 @@ impl Guild { let chorus_request = ChorusRequest { request: Client::new() .get(format!( - "{}/guilds/{}/channels/", + "{}/guilds/{}/channels", user.belongs_to.borrow().urls.api, self.id )) @@ -125,7 +125,7 @@ impl Guild { let chorus_request = ChorusRequest { request: Client::new() .get(format!( - "{}/guilds/{}/", + "{}/guilds/{}", user.belongs_to.borrow().urls.api, guild_id )) @@ -152,7 +152,7 @@ impl Channel { let chorus_request = ChorusRequest { request: Client::new() .post(format!( - "{}/guilds/{}/channels/", + "{}/guilds/{}/channels", user.belongs_to.borrow().urls.api, guild_id )) diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index d3e0e80..28fa68f 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -19,7 +19,7 @@ impl types::GuildMember { member_id: Snowflake, ) -> ChorusResult { let url = format!( - "{}/guilds/{}/members/{}/", + "{}/guilds/{}/members/{}", user.belongs_to.borrow().urls.api, guild_id, member_id @@ -46,7 +46,7 @@ impl types::GuildMember { role_id: Snowflake, ) -> ChorusResult<()> { let url = format!( - "{}/guilds/{}/members/{}/roles/{}/", + "{}/guilds/{}/members/{}/roles/{}", user.belongs_to.borrow().urls.api, guild_id, member_id, @@ -72,7 +72,7 @@ impl types::GuildMember { role_id: Snowflake, ) -> Result<(), crate::errors::ChorusError> { let url = format!( - "{}/guilds/{}/members/{}/roles/{}/", + "{}/guilds/{}/members/{}/roles/{}", user.belongs_to.borrow().urls.api, guild_id, member_id, diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 2787400..91b7bd4 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -19,7 +19,7 @@ impl types::RoleObject { guild_id: Snowflake, ) -> ChorusResult> { let url = format!( - "{}/guilds/{}/roles/", + "{}/guilds/{}/roles", user.belongs_to.borrow().urls.api, guild_id ); @@ -44,7 +44,7 @@ impl types::RoleObject { role_id: Snowflake, ) -> ChorusResult { let url = format!( - "{}/guilds/{}/roles/{}/", + "{}/guilds/{}/roles/{}", user.belongs_to.borrow().urls.api, guild_id, role_id @@ -70,7 +70,7 @@ impl types::RoleObject { role_create_schema: RoleCreateModifySchema, ) -> ChorusResult { let url = format!( - "{}/guilds/{}/roles/", + "{}/guilds/{}/roles", user.belongs_to.borrow().urls.api, guild_id ); @@ -100,7 +100,7 @@ impl types::RoleObject { role_position_update_schema: RolePositionUpdateSchema, ) -> ChorusResult { let url = format!( - "{}/guilds/{}/roles/", + "{}/guilds/{}/roles", user.belongs_to.borrow().urls.api, guild_id ); diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index 9492d8e..ac9c120 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -21,7 +21,7 @@ impl UserMeta { let mut request = ChorusRequest { request: Client::new() .post(format!( - "{}/invites/{}/", + "{}/invites/{}", self.belongs_to.borrow().urls.api, invite_code )) @@ -46,7 +46,7 @@ impl UserMeta { ChorusRequest { request: Client::new() .post(format!( - "{}/users/@me/invites/", + "{}/users/@me/invites", self.belongs_to.borrow().urls.api )) .body(to_string(&code).unwrap()) @@ -72,7 +72,7 @@ impl UserMeta { ChorusRequest { request: Client::new() .post(format!( - "{}/channels/{}/invites/", + "{}/channels/{}/invites", self.belongs_to.borrow().urls.api, channel_id )) diff --git a/src/api/policies/instance/instance.rs b/src/api/policies/instance/instance.rs index 768c7fd..aa529ad 100644 --- a/src/api/policies/instance/instance.rs +++ b/src/api/policies/instance/instance.rs @@ -13,7 +13,7 @@ impl Instance { /// # Reference /// See pub async fn general_configuration_schema(&self) -> ChorusResult { - let endpoint_url = self.urls.api.clone() + "/policies/instance/"; + let endpoint_url = self.urls.api.clone() + "/policies/instance"; let request = match self.client.get(&endpoint_url).send().await { Ok(result) => result, Err(e) => { diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index a446029..3967e8e 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -18,7 +18,7 @@ impl UserMeta { ChorusRequest { request: Client::new() .delete(format!( - "{}/users/@me/guilds/{}/", + "{}/users/@me/guilds/{}", self.belongs_to.borrow().urls.api, guild_id )) diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index a5afaac..41270e1 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -21,7 +21,7 @@ impl UserMeta { user_id: Snowflake, ) -> ChorusResult> { let url = format!( - "{}/users/{}/relationships/", + "{}/users/{}/relationships", self.belongs_to.borrow().urls.api, user_id ); @@ -40,7 +40,7 @@ impl UserMeta { /// See pub async fn get_relationships(&mut self) -> ChorusResult> { let url = format!( - "{}/users/@me/relationships/", + "{}/users/@me/relationships", self.belongs_to.borrow().urls.api ); let chorus_request = ChorusRequest { @@ -61,7 +61,7 @@ impl UserMeta { schema: FriendRequestSendSchema, ) -> ChorusResult<()> { let url = format!( - "{}/users/@me/relationships/", + "{}/users/@me/relationships", self.belongs_to.borrow().urls.api ); let body = to_string(&schema).unwrap(); @@ -85,7 +85,7 @@ impl UserMeta { RelationshipType::None => { let chorus_request = ChorusRequest { request: Client::new() - .delete(format!("{}/users/@me/relationships/{}/", api_url, user_id)) + .delete(format!("{}/users/@me/relationships/{}", api_url, user_id)) .bearer_auth(self.token()), limit_type: LimitType::Global, }; @@ -99,7 +99,7 @@ impl UserMeta { }; let chorus_request = ChorusRequest { request: Client::new() - .put(format!("{}/users/@me/relationships/{}/", api_url, user_id)) + .put(format!("{}/users/@me/relationships/{}", api_url, user_id)) .bearer_auth(self.token()) .body(to_string(&body).unwrap()), limit_type: LimitType::Global, @@ -114,7 +114,7 @@ impl UserMeta { }; let chorus_request = ChorusRequest { request: Client::new() - .put(format!("{}/users/@me/relationships/{}/", api_url, user_id)) + .put(format!("{}/users/@me/relationships/{}", api_url, user_id)) .bearer_auth(self.token()) .body(to_string(&body).unwrap()), limit_type: LimitType::Global, @@ -131,7 +131,7 @@ impl UserMeta { /// See pub async fn remove_relationship(&mut self, user_id: Snowflake) -> ChorusResult<()> { let url = format!( - "{}/users/@me/relationships/{}/", + "{}/users/@me/relationships/{}", self.belongs_to.borrow().urls.api, user_id ); diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 03af2f9..fd28b7a 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -49,7 +49,7 @@ impl UserMeta { return Err(ChorusError::PasswordRequired); } let request = Client::new() - .patch(format!("{}/users/@me/", self.belongs_to.borrow().urls.api)) + .patch(format!("{}/users/@me", self.belongs_to.borrow().urls.api)) .body(to_string(&modify_schema).unwrap()) .bearer_auth(self.token()); let chorus_request = ChorusRequest { @@ -71,7 +71,7 @@ impl UserMeta { pub async fn delete(mut self) -> ChorusResult<()> { let request = Client::new() .post(format!( - "{}/users/@me/delete/", + "{}/users/@me/delete", self.belongs_to.borrow().urls.api )) .bearer_auth(self.token()); @@ -92,7 +92,7 @@ impl User { pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { let url_api = user.belongs_to.borrow().urls.api.clone(); let url = if id.is_none() { - format!("{}/users/@me/", url_api) + format!("{}/users/@me", url_api) } else { format!("{}/users/{}", url_api, id.unwrap()) }; @@ -120,7 +120,7 @@ impl User { instance: &mut Instance, ) -> ChorusResult { let request: reqwest::RequestBuilder = Client::new() - .get(format!("{}/users/@me/settings/", url_api)) + .get(format!("{}/users/@me/settings", url_api)) .bearer_auth(token); let mut user = UserMeta::shell(Rc::new(RefCell::new(instance.clone())), token.clone()).await; From ff47965e995e3ae4dc49b9db5268759532fa5b6e Mon Sep 17 00:00:00 2001 From: fowb Date: Sat, 12 Aug 2023 19:31:31 +0200 Subject: [PATCH 054/237] Change Mutex to RwLock --- src/api/auth/login.rs | 4 ++-- src/api/auth/register.rs | 6 +++--- src/api/users/users.rs | 4 ++-- src/instance.rs | 14 +++++++------- src/types/entities/application.rs | 16 ++++++++-------- src/types/entities/audit_log.rs | 4 ++-- src/types/entities/auto_moderation.rs | 8 ++++---- src/types/entities/channel.rs | 10 +++++----- src/types/entities/emoji.rs | 4 ++-- src/types/entities/guild.rs | 24 ++++++++++++------------ src/types/entities/guild_member.rs | 4 ++-- src/types/entities/integration.rs | 6 +++--- src/types/entities/invite.rs | 4 ++-- src/types/entities/relationship.rs | 4 ++-- src/types/entities/sticker.rs | 4 ++-- src/types/entities/team.rs | 4 ++-- src/types/entities/template.rs | 8 ++++---- src/types/entities/user_settings.rs | 8 ++++---- src/types/entities/voice_state.rs | 4 ++-- src/types/entities/webhook.rs | 6 +++--- tests/channels.rs | 22 +++++++++++----------- tests/members.rs | 2 +- tests/relationships.rs | 24 ++++++++++++------------ 23 files changed, 97 insertions(+), 97 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 447e4c0..3b3ffc6 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -1,6 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use reqwest::Client; use serde_json::to_string; @@ -46,7 +46,7 @@ impl Instance { login_result.token, self.clone_limits_if_some(), login_result.settings, - Arc::new(Mutex::new(object)), + Arc::new(RwLock::new(object)), gateway, ); Ok(user) diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index ea74f29..7beaa76 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use std::{cell::RefCell, rc::Rc}; use reqwest::Client; @@ -52,8 +52,8 @@ impl Instance { Rc::new(RefCell::new(self.clone())), token.clone(), self.clone_limits_if_some(), - Arc::new(Mutex::new(settings)), - Arc::new(Mutex::new(user_object)), + Arc::new(RwLock::new(settings)), + Arc::new(RwLock::new(user_object)), gateway, ); Ok(user) diff --git a/src/api/users/users.rs b/src/api/users/users.rs index fd28b7a..5041bf5 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use std::{cell::RefCell, rc::Rc}; use reqwest::Client; @@ -60,7 +60,7 @@ impl UserMeta { .deserialize_response::(self) .await .unwrap(); - self.object = Arc::new(Mutex::new(user_updated.clone())); + self.object = Arc::new(RwLock::new(user_updated.clone())); Ok(user_updated) } diff --git a/src/instance.rs b/src/instance.rs index 5c2e98b..4ed0f60 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::fmt; use std::rc::Rc; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use reqwest::Client; use serde::{Deserialize, Serialize}; @@ -91,8 +91,8 @@ pub struct UserMeta { pub belongs_to: Rc>, pub token: String, pub limits: Option>, - pub settings: Arc>, - pub object: Arc>, + pub settings: Arc>, + pub object: Arc>, pub gateway: GatewayHandle, } @@ -114,8 +114,8 @@ impl UserMeta { belongs_to: Rc>, token: String, limits: Option>, - settings: Arc>, - object: Arc>, + settings: Arc>, + object: Arc>, gateway: GatewayHandle, ) -> UserMeta { UserMeta { @@ -134,8 +134,8 @@ impl UserMeta { /// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify /// first. pub(crate) async fn shell(instance: Rc>, token: String) -> UserMeta { - let settings = Arc::new(Mutex::new(UserSettings::default())); - let object = Arc::new(Mutex::new(User::default())); + let settings = Arc::new(RwLock::new(UserSettings::default())); + let object = Arc::new(RwLock::new(User::default())); let wss_url = instance.borrow().urls.wss.clone(); // Dummy gateway object let gateway = Gateway::new(wss_url).await.unwrap(); diff --git a/src/types/entities/application.rs b/src/types/entities/application.rs index ad48ab4..0b55626 100644 --- a/src/types/entities/application.rs +++ b/src/types/entities/application.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use bitflags::bitflags; use serde::{Deserialize, Serialize}; @@ -27,7 +27,7 @@ pub struct Application { pub bot_require_code_grant: bool, pub verify_key: String, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub owner: Arc>, + pub owner: Arc>, pub flags: u64, #[cfg(feature = "sqlx")] pub redirect_uris: Option>>, @@ -49,7 +49,7 @@ pub struct Application { #[cfg(feature = "sqlx")] pub install_params: Option>, #[cfg(not(feature = "sqlx"))] - pub install_params: Option>>, + pub install_params: Option>>, pub terms_of_service_url: Option, pub privacy_policy_url: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] @@ -142,7 +142,7 @@ pub struct ApplicationCommand { pub application_id: Snowflake, pub name: String, pub description: String, - pub options: Vec>>, + pub options: Vec>>, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -154,7 +154,7 @@ pub struct ApplicationCommandOption { pub description: String, pub required: bool, pub choices: Vec, - pub options: Arc>>, + pub options: Arc>>, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -190,14 +190,14 @@ pub enum ApplicationCommandOptionType { pub struct ApplicationCommandInteractionData { pub id: Snowflake, pub name: String, - pub options: Vec>>, + pub options: Vec>>, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationCommandInteractionDataOption { pub name: String, pub value: Value, - pub options: Vec>>, + pub options: Vec>>, } #[derive(Debug, Default, Clone, Serialize, Deserialize)] @@ -206,7 +206,7 @@ pub struct GuildApplicationCommandPermissions { pub id: Snowflake, pub application_id: Snowflake, pub guild_id: Snowflake, - pub permissions: Vec>>, + pub permissions: Vec>>, } #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] diff --git a/src/types/entities/audit_log.rs b/src/types/entities/audit_log.rs index e0d05e3..be14f0f 100644 --- a/src/types/entities/audit_log.rs +++ b/src/types/entities/audit_log.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -8,7 +8,7 @@ use crate::types::utils::Snowflake; /// See pub struct AuditLogEntry { pub target_id: Option, - pub changes: Option>>>, + pub changes: Option>>>, pub user_id: Option, pub id: Snowflake, // to:do implement an enum for these types diff --git a/src/types/entities/auto_moderation.rs b/src/types/entities/auto_moderation.rs index afb1ec6..77f4fa2 100644 --- a/src/types/entities/auto_moderation.rs +++ b/src/types/entities/auto_moderation.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -14,8 +14,8 @@ pub struct AutoModerationRule { pub creator_id: Snowflake, pub event_type: AutoModerationRuleEventType, pub trigger_type: AutoModerationRuleTriggerType, - pub trigger_metadata: Arc>, - pub actions: Vec>>, + pub trigger_metadata: Arc>, + pub actions: Vec>>, pub enabled: bool, pub exempt_roles: Vec, pub exempt_channels: Vec, @@ -92,7 +92,7 @@ pub enum AutoModerationRuleKeywordPresetType { pub struct AutoModerationAction { #[serde(rename = "type")] pub action_type: AutoModerationActionType, - pub metadata: Option>>, + pub metadata: Option>>, } #[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)] diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 61754f0..96cf557 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chorus_macros::Updateable; use chrono::Utc; @@ -48,7 +48,7 @@ pub struct Channel { pub last_pin_timestamp: Option, pub managed: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub member: Option>>, + pub member: Option>>, pub member_count: Option, pub message_count: Option, pub name: Option, @@ -58,12 +58,12 @@ pub struct Channel { #[cfg(feature = "sqlx")] pub permission_overwrites: Option>>, #[cfg(not(feature = "sqlx"))] - pub permission_overwrites: Option>>>, + pub permission_overwrites: Option>>>, pub permissions: Option, pub position: Option, pub rate_limit_per_user: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub recipients: Option>>>, + pub recipients: Option>>>, pub rtc_region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub thread_metadata: Option, @@ -156,7 +156,7 @@ pub struct ThreadMember { pub user_id: Option, pub join_timestamp: Option, pub flags: Option, - pub member: Option>>, + pub member: Option>>, } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 38d7da7..f96b2b5 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -17,7 +17,7 @@ pub struct Emoji { #[cfg(not(feature = "sqlx"))] pub roles: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, pub require_colons: Option, pub managed: Option, pub animated: Option, diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 651884f..b95b68a 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -27,13 +27,13 @@ pub struct Guild { #[cfg_attr(feature = "sqlx", sqlx(skip))] pub bans: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub channels: Option>>>, + pub channels: Option>>>, pub default_message_notifications: Option, pub description: Option, pub discovery_splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] #[serde(default)] - pub emojis: Vec>>, + pub emojis: Vec>>, pub explicit_content_filter: Option, //#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))] pub features: Option, @@ -42,7 +42,7 @@ pub struct Guild { pub icon_hash: Option, pub id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub invites: Option>>>, + pub invites: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub joined_at: Option, pub large: Option, @@ -68,7 +68,7 @@ pub struct Guild { pub public_updates_channel_id: Option, pub region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub roles: Option>>>, + pub roles: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub rules_channel: Option, pub rules_channel_id: Option, @@ -81,13 +81,13 @@ pub struct Guild { pub vanity_url_code: Option, pub verification_level: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub voice_states: Option>>>, + pub voice_states: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub webhooks: Option>>>, + pub webhooks: Option>>>, #[cfg(feature = "sqlx")] pub welcome_screen: Option>, #[cfg(not(feature = "sqlx"))] - pub welcome_screen: Option>>, + pub welcome_screen: Option>>, pub widget_channel_id: Option, pub widget_enabled: Option, } @@ -113,11 +113,11 @@ pub struct GuildInvite { pub created_at: DateTime, pub expires_at: Option>, pub guild_id: Snowflake, - pub guild: Option>>, + pub guild: Option>>, pub channel_id: Snowflake, - pub channel: Option>>, + pub channel: Option>>, pub inviter_id: Option, - pub inviter: Option>>, + pub inviter: Option>>, pub target_user_id: Option, pub target_user: Option, pub target_user_type: Option, @@ -151,7 +151,7 @@ pub struct GuildScheduledEvent { pub entity_type: GuildScheduledEventEntityType, pub entity_id: Option, pub entity_metadata: Option, - pub creator: Option>>, + pub creator: Option>>, pub user_count: Option, pub image: Option, } diff --git a/src/types/entities/guild_member.rs b/src/types/entities/guild_member.rs index af63cfb..bf2f93b 100644 --- a/src/types/entities/guild_member.rs +++ b/src/types/entities/guild_member.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -10,7 +10,7 @@ use crate::types::{entities::PublicUser, Snowflake}; /// # Reference /// See pub struct GuildMember { - pub user: Option>>, + pub user: Option>>, pub nick: Option, pub avatar: Option, pub roles: Vec, diff --git a/src/types/entities/integration.rs b/src/types/entities/integration.rs index a95c33c..0913213 100644 --- a/src/types/entities/integration.rs +++ b/src/types/entities/integration.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -23,14 +23,14 @@ pub struct Integration { pub expire_behaviour: Option, pub expire_grace_period: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub account: IntegrationAccount, pub synced_at: Option>, pub subscriber_count: Option, pub revoked: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub application: Option>>, + pub application: Option>>, pub scopes: Option>, } diff --git a/src/types/entities/invite.rs b/src/types/entities/invite.rs index 7eefd98..1e6befc 100644 --- a/src/types/entities/invite.rs +++ b/src/types/entities/invite.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -70,7 +70,7 @@ pub enum NSFWLevel { /// See #[derive(Debug, Serialize, Deserialize)] pub struct InviteStageInstance { - pub members: Vec>>, + pub members: Vec>>, pub participant_count: i32, pub speaker_count: i32, pub topic: String, diff --git a/src/types/entities/relationship.rs b/src/types/entities/relationship.rs index a5f5bcb..576d99a 100644 --- a/src/types/entities/relationship.rs +++ b/src/types/entities/relationship.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -15,7 +15,7 @@ pub struct Relationship { #[serde(rename = "type")] pub relationship_type: RelationshipType, pub nickname: Option, - pub user: Arc>, + pub user: Arc>, pub since: Option>, } diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index 42edb7f..5413112 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -24,7 +24,7 @@ pub struct Sticker { pub available: Option, pub guild_id: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, pub sort_value: Option, } diff --git a/src/types/entities/team.rs b/src/types/entities/team.rs index fe6562b..8e32f55 100644 --- a/src/types/entities/team.rs +++ b/src/types/entities/team.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -21,5 +21,5 @@ pub struct TeamMember { pub membership_state: u8, pub permissions: Vec, pub team_id: Snowflake, - pub user: Arc>, + pub user: Arc>, } diff --git a/src/types/entities/template.rs b/src/types/entities/template.rs index 0550e9e..1305a98 100644 --- a/src/types/entities/template.rs +++ b/src/types/entities/template.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -18,13 +18,13 @@ pub struct GuildTemplate { pub usage_count: Option, pub creator_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub creator: Arc>, + pub creator: Arc>, pub created_at: DateTime, pub updated_at: DateTime, pub source_guild_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub source_guild: Vec>>, + pub source_guild: Vec>>, // Unsure how a {recursive: Guild} looks like, might be a Vec? #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub serialized_source_guild: Vec>>, + pub serialized_source_guild: Vec>>, } diff --git a/src/types/entities/user_settings.rs b/src/types/entities/user_settings.rs index 4705a92..1be2c0a 100644 --- a/src/types/entities/user_settings.rs +++ b/src/types/entities/user_settings.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{serde::ts_milliseconds_option, Utc}; use serde::{Deserialize, Serialize}; @@ -75,7 +75,7 @@ pub struct UserSettings { #[cfg(not(feature = "sqlx"))] pub restricted_guilds: Vec, pub show_current_game: bool, - pub status: Arc>, + pub status: Arc>, pub stream_notifications_enabled: bool, pub theme: UserTheme, pub timezone_offset: i16, @@ -111,7 +111,7 @@ impl Default for UserSettings { render_reactions: true, restricted_guilds: Default::default(), show_current_game: true, - status: Arc::new(Mutex::new(UserStatus::Online)), + status: Arc::new(RwLock::new(UserStatus::Online)), stream_notifications_enabled: false, theme: UserTheme::Dark, timezone_offset: 0, @@ -151,5 +151,5 @@ pub struct GuildFolder { #[derive(Debug, Serialize, Deserialize)] pub struct LoginResult { pub token: String, - pub settings: Arc>, + pub settings: Arc>, } diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index 29b8e6e..9f6a2c0 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -16,7 +16,7 @@ pub struct VoiceState { pub guild: Option, pub channel_id: Option, pub user_id: Snowflake, - pub member: Option>>, + pub member: Option>>, pub session_id: Snowflake, pub token: Option, pub deaf: bool, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index f8b6530..079f584 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, RwLock}; use serde::{Deserialize, Serialize}; @@ -22,10 +22,10 @@ pub struct Webhook { pub application_id: Snowflake, #[serde(skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub user: Option>>, + pub user: Option>>, #[serde(skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub source_guild: Option>>, + pub source_guild: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub url: Option, } diff --git a/tests/channels.rs b/tests/channels.rs index d810c10..8dafc48 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -59,7 +59,7 @@ async fn modify_channel() { PermissionFlags::MANAGE_CHANNELS, PermissionFlags::MANAGE_MESSAGES, ])); - let user_id: types::Snowflake = bundle.user.object.lock().unwrap().id; + let user_id: types::Snowflake = bundle.user.object.read().unwrap().id; let permission_override = PermissionOverwrite { id: user_id, overwrite_type: "1".to_string(), @@ -144,7 +144,7 @@ async fn create_dm() { let other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { - recipients: Some(Vec::from([other_user.object.lock().unwrap().id])), + recipients: Some(Vec::from([other_user.object.read().unwrap().id])), access_tokens: None, nicks: None, }; @@ -160,11 +160,11 @@ async fn create_dm() { .unwrap() .get(0) .unwrap() - .lock() + .read() .unwrap() .id .clone(), - other_user.object.lock().unwrap().id + other_user.object.read().unwrap().id ); assert_eq!( dm_channel @@ -173,11 +173,11 @@ async fn create_dm() { .unwrap() .get(1) .unwrap() - .lock() + .read() .unwrap() .id .clone(), - user.object.lock().unwrap().id.clone() + user.object.read().unwrap().id.clone() ); common::teardown(bundle).await; } @@ -189,9 +189,9 @@ async fn remove_add_person_from_to_dm() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let mut third_user = bundle.create_user("integrationtestuser3").await; - let third_user_id = third_user.object.lock().unwrap().id; - let other_user_id = other_user.object.lock().unwrap().id; - let user_id = bundle.user.object.lock().unwrap().id; + let third_user_id = third_user.object.read().unwrap().id; + let other_user_id = other_user.object.read().unwrap().id; + let user_id = bundle.user.object.read().unwrap().id; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { recipients: Some(Vec::from([other_user_id, third_user_id])), @@ -234,7 +234,7 @@ async fn remove_add_person_from_to_dm() { .unwrap() .get(0) .unwrap() - .lock() + .read() .unwrap() .id, other_user_id @@ -246,7 +246,7 @@ async fn remove_add_person_from_to_dm() { .unwrap() .get(1) .unwrap() - .lock() + .read() .unwrap() .id, user_id diff --git a/tests/members.rs b/tests/members.rs index a314be7..aae8db0 100644 --- a/tests/members.rs +++ b/tests/members.rs @@ -7,7 +7,7 @@ async fn add_remove_role() -> ChorusResult<()> { let mut bundle = common::setup().await; let guild = bundle.guild.id; let role = bundle.role.id; - let member_id = bundle.user.object.lock().unwrap().id; + let member_id = bundle.user.object.read().unwrap().id; GuildMember::add_role(&mut bundle.user, guild, member_id, role).await?; let member = GuildMember::get(&mut bundle.user, guild, member_id) .await diff --git a/tests/relationships.rs b/tests/relationships.rs index 2773474..09ddab0 100644 --- a/tests/relationships.rs +++ b/tests/relationships.rs @@ -7,9 +7,9 @@ async fn test_get_mutual_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let username = user.object.lock().unwrap().username.clone(); - let discriminator = user.object.lock().unwrap().discriminator.clone(); - let other_user_id: types::Snowflake = other_user.object.lock().unwrap().id; + let username = user.object.read().unwrap().username.clone(); + let discriminator = user.object.read().unwrap().discriminator.clone(); + let other_user_id: types::Snowflake = other_user.object.read().unwrap().id; let friend_request_schema = types::FriendRequestSendSchema { username, discriminator: Some(discriminator), @@ -28,8 +28,8 @@ async fn test_get_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let username = user.object.lock().unwrap().username.clone(); - let discriminator = user.object.lock().unwrap().discriminator.clone(); + let username = user.object.read().unwrap().username.clone(); + let discriminator = user.object.read().unwrap().discriminator.clone(); let friend_request_schema = types::FriendRequestSendSchema { username, discriminator: Some(discriminator), @@ -41,7 +41,7 @@ async fn test_get_relationships() { let relationships = user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - other_user.object.lock().unwrap().id + other_user.object.read().unwrap().id ); common::teardown(bundle).await } @@ -51,8 +51,8 @@ async fn test_modify_relationship_friends() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let user_id: types::Snowflake = user.object.lock().unwrap().id; - let other_user_id: types::Snowflake = other_user.object.lock().unwrap().id; + let user_id: types::Snowflake = user.object.read().unwrap().id; + let other_user_id: types::Snowflake = other_user.object.read().unwrap().id; other_user .modify_user_relationship(user_id, types::RelationshipType::Friends) @@ -61,7 +61,7 @@ async fn test_modify_relationship_friends() { let relationships = user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - other_user.object.lock().unwrap().id + other_user.object.read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, @@ -70,7 +70,7 @@ async fn test_modify_relationship_friends() { let relationships = other_user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - user.object.lock().unwrap().id + user.object.read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, @@ -102,7 +102,7 @@ async fn test_modify_relationship_block() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let user_id: types::Snowflake = user.object.lock().unwrap().id; + let user_id: types::Snowflake = user.object.read().unwrap().id; other_user .modify_user_relationship(user_id, types::RelationshipType::Blocked) @@ -113,7 +113,7 @@ async fn test_modify_relationship_block() { let relationships = other_user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - user.object.lock().unwrap().id + user.object.read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, From a0c9f6fb148c14bece14cccfd4e47a1ea1365a36 Mon Sep 17 00:00:00 2001 From: fowb Date: Sat, 12 Aug 2023 19:47:11 +0200 Subject: [PATCH 055/237] Change observe() to take Arc> --- src/gateway.rs | 18 ++++++++++++------ tests/gateway.rs | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index eaac29f..f147584 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -6,7 +6,7 @@ use async_trait::async_trait; use std::any::Any; use std::collections::HashMap; use std::fmt::Debug; -use std::sync::Arc; +use std::sync::{Arc, RwLock}; use std::time::Duration; use tokio::sync::watch; use tokio::time::sleep_until; @@ -196,20 +196,26 @@ impl GatewayHandle { .unwrap(); } - pub async fn observe(&self, object: T) -> watch::Receiver { + pub async fn observe( + &self, + object: Arc>, + ) -> watch::Receiver>> { let mut store = self.store.lock().await; - if let Some(channel) = store.get(&object.id()) { + if let Some(channel) = store.get(&object.clone().read().unwrap().id()) { let (_, rx) = channel - .downcast_ref::<(watch::Sender, watch::Receiver)>() + .downcast_ref::<( + watch::Sender>>, + watch::Receiver>>, + )>() .unwrap_or_else(|| { panic!( "Snowflake {} already exists in the store, but it is not of type T.", - object.id() + object.read().unwrap().id() ) }); rx.clone() } else { - let id = object.id(); + let id = object.read().unwrap().id(); let channel = watch::channel(object); let receiver = channel.1.clone(); store.insert(id, Box::new(channel)); diff --git a/tests/gateway.rs b/tests/gateway.rs index 21a2018..15f58d8 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -29,7 +29,7 @@ async fn test_gateway_authenticate() { #[tokio::test] async fn test_self_updating_structs() { let mut bundle = common::setup().await; - let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; + let channel_updater = bundle.user.gateway.observe(bundle.channel).await; let received_channel = channel_updater.borrow().clone(); assert_eq!(received_channel, bundle.channel); let channel = &mut bundle.channel; From 63a4141bde084a2a4f14384205fe517a323ec251 Mon Sep 17 00:00:00 2001 From: fowb Date: Sat, 12 Aug 2023 22:40:07 +0200 Subject: [PATCH 056/237] Add fixme comment --- src/api/channels/channels.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 0c6f3e3..735d69f 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -67,6 +67,7 @@ impl Channel { channel_id: Snowflake, user: &mut UserMeta, ) -> ChorusResult { + // FIXME: Do not return a Channel. let chorus_request = ChorusRequest { request: Client::new() .patch(format!( From 29d4ef23a2771367bef3c2da0104313d6ac73289 Mon Sep 17 00:00:00 2001 From: fowb Date: Sat, 12 Aug 2023 22:40:40 +0200 Subject: [PATCH 057/237] Change T: Updateable to Arc> --- tests/channels.rs | 19 ++++++++++++------- tests/common/mod.rs | 19 ++++++++++--------- tests/gateway.rs | 24 ++++++++++++++++++------ 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/tests/channels.rs b/tests/channels.rs index 8dafc48..5641b1f 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -8,11 +8,11 @@ mod common; #[tokio::test] async fn get_channel() { let mut bundle = common::setup().await; - let bundle_channel = bundle.channel.clone(); + let bundle_channel = bundle.channel.read().unwrap(); let bundle_user = &mut bundle.user; assert_eq!( - bundle_channel, + *bundle_channel, Channel::get(bundle_user, bundle_channel.id).await.unwrap() ); common::teardown(bundle).await @@ -21,7 +21,7 @@ async fn get_channel() { #[tokio::test] async fn delete_channel() { let mut bundle = common::setup().await; - let result = Channel::delete(bundle.channel.clone(), &mut bundle.user).await; + let result = Channel::delete(*bundle.channel.write().unwrap(), &mut bundle.user).await; assert!(result.is_ok()); common::teardown(bundle).await } @@ -50,16 +50,21 @@ async fn modify_channel() { default_thread_rate_limit_per_user: None, video_quality_mode: None, }; - let modified_channel = Channel::modify(channel, modify_data, channel.id, &mut bundle.user) - .await - .unwrap(); + let modified_channel = Channel::modify( + channel.read().as_ref().unwrap(), + modify_data, + channel.read().unwrap().id, + &mut bundle.user, + ) + .await + .unwrap(); assert_eq!(modified_channel.name, Some(CHANNEL_NAME.to_string())); let permission_override = PermissionFlags::from_vec(Vec::from([ PermissionFlags::MANAGE_CHANNELS, PermissionFlags::MANAGE_MESSAGES, ])); - let user_id: types::Snowflake = bundle.user.object.read().unwrap().id; + let user_id: types::Snowflake = bundle.user.read().unwrap().object.read().unwrap().id; let permission_override = PermissionOverwrite { id: user_id, overwrite_type: "1".to_string(), diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 747a8cd..029df2d 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, RwLock}; + use chorus::gateway::Gateway; use chorus::{ instance::{Instance, UserMeta}, @@ -14,9 +16,9 @@ pub(crate) struct TestBundle { pub urls: UrlBundle, pub user: UserMeta, pub instance: Instance, - pub guild: Guild, - pub role: RoleObject, - pub channel: Channel, + pub guild: Arc>, + pub role: Arc>, + pub channel: Arc>, } #[allow(unused)] @@ -113,17 +115,16 @@ pub(crate) async fn setup() -> TestBundle { urls, user, instance, - guild, - role, - channel, + guild: Arc::new(RwLock::new(guild)), + role: Arc::new(RwLock::new(role)), + channel: Arc::new(RwLock::new(channel)), } } // Teardown method to clean up after a test. #[allow(dead_code)] pub(crate) async fn teardown(mut bundle: TestBundle) { - Guild::delete(&mut bundle.user, bundle.guild.id) - .await - .unwrap(); + let id = bundle.guild.read().unwrap().id; + Guild::delete(&mut bundle.user, id).await.unwrap(); bundle.user.delete().await.unwrap() } diff --git a/tests/gateway.rs b/tests/gateway.rs index 15f58d8..9c77b7e 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -29,18 +29,30 @@ async fn test_gateway_authenticate() { #[tokio::test] async fn test_self_updating_structs() { let mut bundle = common::setup().await; - let channel_updater = bundle.user.gateway.observe(bundle.channel).await; + let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; let received_channel = channel_updater.borrow().clone(); - assert_eq!(received_channel, bundle.channel); + assert_eq!( + *received_channel.read().unwrap(), + *bundle.channel.read().unwrap() + ); let channel = &mut bundle.channel; let modify_data = types::ChannelModifySchema { name: Some("beepboop".to_string()), ..Default::default() }; - Channel::modify(channel, modify_data, channel.id, &mut bundle.user) - .await - .unwrap(); + let channel_id = channel.read().unwrap().id; + Channel::modify( + channel.read().as_ref().unwrap(), + modify_data, + channel_id, + &mut bundle.user, + ) + .await + .unwrap(); let received_channel = channel_updater.borrow(); - assert_eq!(received_channel.name.as_ref().unwrap(), "beepboop"); + assert_eq!( + received_channel.read().unwrap().name.as_ref().unwrap(), + "beepboop" + ); common::teardown(bundle).await } From 73cc139e7805dc87ea8e196009780c5e0b69d099 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 13 Aug 2023 15:52:16 +0200 Subject: [PATCH 058/237] Moddify observe to still store T internally --- src/gateway.rs | 11 ++++------- tests/gateway.rs | 35 +++++++++++++++++------------------ 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index f147584..145eaa0 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -196,17 +196,14 @@ impl GatewayHandle { .unwrap(); } - pub async fn observe( + pub async fn observe( &self, object: Arc>, - ) -> watch::Receiver>> { + ) -> watch::Receiver { let mut store = self.store.lock().await; if let Some(channel) = store.get(&object.clone().read().unwrap().id()) { let (_, rx) = channel - .downcast_ref::<( - watch::Sender>>, - watch::Receiver>>, - )>() + .downcast_ref::<(watch::Sender, watch::Receiver)>() .unwrap_or_else(|| { panic!( "Snowflake {} already exists in the store, but it is not of type T.", @@ -216,7 +213,7 @@ impl GatewayHandle { rx.clone() } else { let id = object.read().unwrap().id(); - let channel = watch::channel(object); + let channel = watch::channel(object.read().unwrap().clone()); let receiver = channel.1.clone(); store.insert(id, Box::new(channel)); receiver diff --git a/tests/gateway.rs b/tests/gateway.rs index 9c77b7e..b0570c0 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,7 @@ mod common; use chorus::gateway::*; -use chorus::types::{self, Channel}; +use chorus::types::{self, Channel, ChannelModifySchema}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -31,28 +31,27 @@ async fn test_self_updating_structs() { let mut bundle = common::setup().await; let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; let received_channel = channel_updater.borrow().clone(); + assert_eq!(received_channel, bundle.channel.read().unwrap().clone()); + + let updater = bundle.user.gateway.observe(bundle.channel.clone()).await; assert_eq!( - *received_channel.read().unwrap(), - *bundle.channel.read().unwrap() + updater.borrow().clone().name.unwrap(), + bundle.channel.read().unwrap().clone().name.unwrap() ); - let channel = &mut bundle.channel; - let modify_data = types::ChannelModifySchema { - name: Some("beepboop".to_string()), + + let channel = bundle.channel.read().unwrap().clone(); + let modify_schema = ChannelModifySchema { + name: Some("selfupdating".to_string()), ..Default::default() }; - let channel_id = channel.read().unwrap().id; - Channel::modify( - channel.read().as_ref().unwrap(), - modify_data, - channel_id, - &mut bundle.user, - ) - .await - .unwrap(); - let received_channel = channel_updater.borrow(); + Channel::modify(&channel, modify_schema, &mut bundle.user) + .await + .unwrap(); + assert_eq!( - received_channel.read().unwrap().name.as_ref().unwrap(), - "beepboop" + updater.borrow().clone().name.unwrap(), + "selfupdating".to_string() ); + common::teardown(bundle).await } From 20cd457c04ce8e0c716fc408efbb7c5e0e3e362b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 13 Aug 2023 15:54:07 +0200 Subject: [PATCH 059/237] Change tests to deal with `Arc>`'s --- tests/channels.rs | 44 ++++++++++++++++++-------------------------- tests/guilds.rs | 6 ++---- tests/invites.rs | 7 ++++--- tests/members.rs | 4 ++-- tests/messages.rs | 15 ++++----------- tests/roles.rs | 12 ++++++------ 6 files changed, 36 insertions(+), 52 deletions(-) diff --git a/tests/channels.rs b/tests/channels.rs index 5641b1f..3043c00 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -8,11 +8,11 @@ mod common; #[tokio::test] async fn get_channel() { let mut bundle = common::setup().await; - let bundle_channel = bundle.channel.read().unwrap(); + let bundle_channel = bundle.channel.read().unwrap().clone(); let bundle_user = &mut bundle.user; assert_eq!( - *bundle_channel, + bundle_channel, Channel::get(bundle_user, bundle_channel.id).await.unwrap() ); common::teardown(bundle).await @@ -21,7 +21,8 @@ async fn get_channel() { #[tokio::test] async fn delete_channel() { let mut bundle = common::setup().await; - let result = Channel::delete(*bundle.channel.write().unwrap(), &mut bundle.user).await; + let channel_guard = bundle.channel.write().unwrap().clone(); + let result = Channel::delete(channel_guard, &mut bundle.user).await; assert!(result.is_ok()); common::teardown(bundle).await } @@ -30,7 +31,7 @@ async fn delete_channel() { async fn modify_channel() { const CHANNEL_NAME: &str = "beepboop"; let mut bundle = common::setup().await; - let channel = &mut bundle.channel; + let channel = &mut bundle.channel.read().unwrap().clone(); let modify_data: types::ChannelModifySchema = types::ChannelModifySchema { name: Some(CHANNEL_NAME.to_string()), channel_type: None, @@ -50,37 +51,28 @@ async fn modify_channel() { default_thread_rate_limit_per_user: None, video_quality_mode: None, }; - let modified_channel = Channel::modify( - channel.read().as_ref().unwrap(), - modify_data, - channel.read().unwrap().id, - &mut bundle.user, - ) - .await - .unwrap(); + let modified_channel = Channel::modify(channel, modify_data, &mut bundle.user) + .await + .unwrap(); assert_eq!(modified_channel.name, Some(CHANNEL_NAME.to_string())); let permission_override = PermissionFlags::from_vec(Vec::from([ PermissionFlags::MANAGE_CHANNELS, PermissionFlags::MANAGE_MESSAGES, ])); - let user_id: types::Snowflake = bundle.user.read().unwrap().object.read().unwrap().id; + let user_id: types::Snowflake = bundle.user.object.read().unwrap().id; let permission_override = PermissionOverwrite { id: user_id, overwrite_type: "1".to_string(), allow: permission_override, deny: "0".to_string(), }; + let channel_id: Snowflake = bundle.channel.read().unwrap().id; + Channel::edit_permissions(&mut bundle.user, channel_id, permission_override.clone()) + .await + .unwrap(); - Channel::edit_permissions( - &mut bundle.user, - bundle.channel.id, - permission_override.clone(), - ) - .await - .unwrap(); - - Channel::delete_permission(&mut bundle.user, bundle.channel.id, permission_override.id) + Channel::delete_permission(&mut bundle.user, channel_id, permission_override.id) .await .unwrap(); @@ -90,7 +82,7 @@ async fn modify_channel() { #[tokio::test] async fn get_channel_messages() { let mut bundle = common::setup().await; - + let channel_id: Snowflake = bundle.channel.read().unwrap().id; // First create some messages to read for _ in 0..10 { let _ = bundle @@ -100,7 +92,7 @@ async fn get_channel_messages() { content: Some("A Message!".to_string()), ..Default::default() }, - bundle.channel.id, + channel_id, ) .await .unwrap(); @@ -109,7 +101,7 @@ async fn get_channel_messages() { assert_eq!( Channel::messages( GetChannelMessagesSchema::before(Snowflake::generate()), - bundle.channel.id, + channel_id, &mut bundle.user, ) .await @@ -133,7 +125,7 @@ async fn get_channel_messages() { assert!(Channel::messages( GetChannelMessagesSchema::after(Snowflake::generate()), - bundle.channel.id, + channel_id, &mut bundle.user, ) .await diff --git a/tests/guilds.rs b/tests/guilds.rs index cc33b30..3d29d43 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -27,9 +27,7 @@ async fn guild_creation_deletion() { #[tokio::test] async fn get_channels() { let mut bundle = common::setup().await; - println!( - "{:?}", - bundle.guild.channels(&mut bundle.user).await.unwrap() - ); + let guild = bundle.guild.read().unwrap().clone(); + println!("{:?}", guild.channels(&mut bundle.user).await.unwrap()); common::teardown(bundle).await; } diff --git a/tests/invites.rs b/tests/invites.rs index e25fea5..ab264d4 100644 --- a/tests/invites.rs +++ b/tests/invites.rs @@ -3,11 +3,12 @@ use chorus::types::CreateChannelInviteSchema; #[tokio::test] async fn create_accept_invite() { let mut bundle = common::setup().await; - let channel = bundle.channel.clone(); + let channel = bundle.channel.read().unwrap().clone(); let mut other_user = bundle.create_user("testuser1312").await; let user = &mut bundle.user; let create_channel_invite_schema = CreateChannelInviteSchema::default(); - assert!(chorus::types::Guild::get(bundle.guild.id, &mut other_user) + let guild = bundle.guild.read().unwrap().clone(); + assert!(chorus::types::Guild::get(guild.id, &mut other_user) .await .is_err()); let invite = user @@ -16,7 +17,7 @@ async fn create_accept_invite() { .unwrap(); other_user.accept_invite(&invite.code, None).await.unwrap(); - assert!(chorus::types::Guild::get(bundle.guild.id, &mut other_user) + assert!(chorus::types::Guild::get(guild.id, &mut other_user) .await .is_ok()); common::teardown(bundle).await; diff --git a/tests/members.rs b/tests/members.rs index aae8db0..fbab772 100644 --- a/tests/members.rs +++ b/tests/members.rs @@ -5,8 +5,8 @@ mod common; #[tokio::test] async fn add_remove_role() -> ChorusResult<()> { let mut bundle = common::setup().await; - let guild = bundle.guild.id; - let role = bundle.role.id; + let guild = bundle.guild.read().unwrap().id; + let role = bundle.role.read().unwrap().id; let member_id = bundle.user.object.read().unwrap().id; GuildMember::add_role(&mut bundle.user, guild, member_id, role).await?; let member = GuildMember::get(&mut bundle.user, guild, member_id) diff --git a/tests/messages.rs b/tests/messages.rs index af6ee5b..417ca54 100644 --- a/tests/messages.rs +++ b/tests/messages.rs @@ -12,11 +12,8 @@ async fn send_message() { content: Some("A Message!".to_string()), ..Default::default() }; - let _ = bundle - .user - .send_message(message, bundle.channel.id) - .await - .unwrap(); + let channel = bundle.channel.read().unwrap().clone(); + let _ = bundle.user.send_message(message, channel.id).await.unwrap(); common::teardown(bundle).await } @@ -50,13 +47,9 @@ async fn send_message_attachment() { attachments: Some(vec![attachment.clone()]), ..Default::default() }; - + let channel = bundle.channel.read().unwrap().clone(); let vec_attach = vec![attachment.clone()]; let _arg = Some(&vec_attach); - bundle - .user - .send_message(message, bundle.channel.id) - .await - .unwrap(); + bundle.user.send_message(message, channel.id).await.unwrap(); common::teardown(bundle).await } diff --git a/tests/roles.rs b/tests/roles.rs index f45fb62..7876e5d 100644 --- a/tests/roles.rs +++ b/tests/roles.rs @@ -17,12 +17,12 @@ async fn create_and_get_roles() { position: None, color: None, }; - let guild = bundle.guild.id; - let role = types::RoleObject::create(&mut bundle.user, guild, role_create_schema) + let guild_id = bundle.guild.read().unwrap().id; + let role = types::RoleObject::create(&mut bundle.user, guild_id, role_create_schema) .await .unwrap(); - let expected = types::RoleObject::get_all(&mut bundle.user, guild) + let expected = types::RoleObject::get_all(&mut bundle.user, guild_id) .await .unwrap()[2] .clone(); @@ -34,9 +34,9 @@ async fn create_and_get_roles() { #[tokio::test] async fn get_singular_role() { let mut bundle = common::setup().await; - let guild_id = bundle.guild.id; - let role_id = bundle.role.id; - let role = bundle.role.clone(); + let guild_id = bundle.guild.read().unwrap().id; + let role_id = bundle.role.read().unwrap().id; + let role = bundle.role.read().unwrap().clone(); let same_role = chorus::types::RoleObject::get(&mut bundle.user, guild_id, role_id) .await .unwrap(); From f9c3f55d952ae42769ac0d082ac0cdcfcba03a44 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 13 Aug 2023 15:54:25 +0200 Subject: [PATCH 060/237] Remove channel_id argument from modify. WHY WAS IT THERE TO BEGIN WITH LOL --- src/api/channels/channels.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 735d69f..eb0c794 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -64,10 +64,10 @@ impl Channel { pub async fn modify( &self, modify_data: ChannelModifySchema, - channel_id: Snowflake, user: &mut UserMeta, ) -> ChorusResult { // FIXME: Do not return a Channel. + let channel_id = self.id; let chorus_request = ChorusRequest { request: Client::new() .patch(format!( From c0c873d460111188539129499aaa5ea3d4cb5696 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 13 Aug 2023 16:44:58 +0200 Subject: [PATCH 061/237] Update test to match code changes --- tests/gateway.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index b0570c0..2a9e38c 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -30,12 +30,19 @@ async fn test_gateway_authenticate() { async fn test_self_updating_structs() { let mut bundle = common::setup().await; let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; - let received_channel = channel_updater.borrow().clone(); + let received_channel = channel_updater.borrow().clone().read().unwrap().clone(); assert_eq!(received_channel, bundle.channel.read().unwrap().clone()); let updater = bundle.user.gateway.observe(bundle.channel.clone()).await; assert_eq!( - updater.borrow().clone().name.unwrap(), + updater + .borrow() + .clone() + .read() + .unwrap() + .clone() + .name + .unwrap(), bundle.channel.read().unwrap().clone().name.unwrap() ); @@ -49,7 +56,7 @@ async fn test_self_updating_structs() { .unwrap(); assert_eq!( - updater.borrow().clone().name.unwrap(), + updater.borrow().read().unwrap().clone().name.unwrap(), "selfupdating".to_string() ); From 33357db291b0cf2c505eafc89a814cdb91387688 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 13 Aug 2023 16:46:21 +0200 Subject: [PATCH 062/237] Change observe() again, pass Arc> into message.update(), Add comment explaining closure --- src/gateway.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 145eaa0..3e0c4f3 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -199,11 +199,14 @@ impl GatewayHandle { pub async fn observe( &self, object: Arc>, - ) -> watch::Receiver { + ) -> watch::Receiver>> { let mut store = self.store.lock().await; if let Some(channel) = store.get(&object.clone().read().unwrap().id()) { let (_, rx) = channel - .downcast_ref::<(watch::Sender, watch::Receiver)>() + .downcast_ref::<( + watch::Sender>>, + watch::Receiver>>, + )>() .unwrap_or_else(|| { panic!( "Snowflake {} already exists in the store, but it is not of type T.", @@ -213,7 +216,7 @@ impl GatewayHandle { rx.clone() } else { let id = object.read().unwrap().id(); - let channel = watch::channel(object.read().unwrap().clone()); + let channel = watch::channel(object); let receiver = channel.1.clone(); store.insert(id, Box::new(channel)); receiver @@ -481,8 +484,11 @@ impl Gateway { $( let message: $message_type = message; if let Some(to_update) = self.store.lock().await.get(&message.id()) { - if let Some((tx, _)) = to_update.downcast_ref::<(watch::Sender<$update_type>, watch::Receiver<$update_type>)>() { - tx.send_modify(|object| message.update(object)); + if let Some((tx, _)) = to_update.downcast_ref::<(watch::Sender>>, watch::Receiver>>)>() { + // `object` is the current value of the `watch::channel`. It's being passed into `message.update()` to be modified + // within the closure function. Then, this closure is passed to the `tx.send_modify()` method which applies the + // modification to the current value of the watch channel. + tx.send_modify(|object| message.update(object.clone())); } else { warn!("Received {} for {}, but it has been observed to be a different type!", $name, message.id()) } From 0f00d5d283aec9f719d34080108835f09b3c2063 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 13 Aug 2023 16:46:57 +0200 Subject: [PATCH 063/237] Change UpdateMessage to write into RwLock --- src/types/events/channel.rs | 7 +++++-- src/types/events/mod.rs | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 002230c..000bc17 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, RwLock}; + use crate::types::events::WebSocketEvent; use crate::types::{entities::Channel, Snowflake}; use chrono::{DateTime, Utc}; @@ -34,8 +36,9 @@ pub struct ChannelUpdate { impl WebSocketEvent for ChannelUpdate {} impl UpdateMessage for ChannelUpdate { - fn update(&self, object_to_update: &mut Channel) { - *object_to_update = self.channel.clone(); + fn update(&self, object_to_update: Arc>) { + let mut write = object_to_update.write().unwrap(); + *write = self.channel.clone(); } fn id(&self) -> Snowflake { self.channel.id diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index d477800..0413ac9 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, RwLock}; + use serde::{Deserialize, Serialize}; pub use application::*; @@ -113,6 +115,6 @@ pub(crate) trait UpdateMessage: Clone where T: Updateable, { - fn update(&self, object_to_update: &mut T); + fn update(&self, object_to_update: Arc>); fn id(&self) -> Snowflake; } From 614c7bb2b265d1d615c2ec88c6794a5568e5ab91 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 14 Aug 2023 00:02:03 +0200 Subject: [PATCH 064/237] Change UserMeta::get() to take self instead of Self --- src/api/users/users.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 5041bf5..43e4dfd 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -21,8 +21,8 @@ impl UserMeta { /// # Reference /// See and /// - pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { - User::get(user, id).await + pub async fn get(&mut self, id: Option<&String>) -> ChorusResult { + User::get(self, id).await } /// Gets the user's settings. @@ -56,12 +56,7 @@ impl UserMeta { request, limit_type: LimitType::default(), }; - let user_updated = chorus_request - .deserialize_response::(self) - .await - .unwrap(); - self.object = Arc::new(RwLock::new(user_updated.clone())); - Ok(user_updated) + chorus_request.deserialize_response::(self).await } /// Deletes the user from the Instance. @@ -104,7 +99,11 @@ impl User { match chorus_request.send_request(user).await { Ok(result) => { let result_text = result.text().await.unwrap(); - Ok(serde_json::from_str::(&result_text).unwrap()) + let api_user = serde_json::from_str::(&result_text).unwrap(); + user.gateway + .observe(Arc::new(RwLock::new(api_user.clone()))) + .await; + Ok(api_user) } Err(e) => Err(e), } From 45d68b4da460451cac7cdf1b081e772caf3e64ec Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 14 Aug 2023 00:02:30 +0200 Subject: [PATCH 065/237] Rename get to get_user --- src/api/users/users.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 43e4dfd..b76f4b4 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -21,7 +21,7 @@ impl UserMeta { /// # Reference /// See and /// - pub async fn get(&mut self, id: Option<&String>) -> ChorusResult { + pub async fn get_user(&mut self, id: Option<&String>) -> ChorusResult { User::get(self, id).await } @@ -99,11 +99,7 @@ impl User { match chorus_request.send_request(user).await { Ok(result) => { let result_text = result.text().await.unwrap(); - let api_user = serde_json::from_str::(&result_text).unwrap(); - user.gateway - .observe(Arc::new(RwLock::new(api_user.clone()))) - .await; - Ok(api_user) + Ok(serde_json::from_str::(&result_text).unwrap()) } Err(e) => Err(e), } From 02be1e786ddaa779007e2883fb3469bc7bdcee48 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 14 Aug 2023 00:04:53 +0200 Subject: [PATCH 066/237] Remove stupid comment from me --- src/api/channels/channels.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index eb0c794..1e8f93c 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -66,7 +66,6 @@ impl Channel { modify_data: ChannelModifySchema, user: &mut UserMeta, ) -> ChorusResult { - // FIXME: Do not return a Channel. let channel_id = self.id; let chorus_request = ChorusRequest { request: Client::new() From 6dd9f845735cc6919bd7e6efb3c6024eba2da6aa Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 14 Aug 2023 00:04:58 +0200 Subject: [PATCH 067/237] Remove unused import --- src/api/users/users.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/users/users.rs b/src/api/users/users.rs index b76f4b4..ff0638d 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -1,4 +1,3 @@ -use std::sync::{Arc, RwLock}; use std::{cell::RefCell, rc::Rc}; use reqwest::Client; From 2329cc22436b9b405f8de647d2a3f96345616452 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 14 Aug 2023 17:18:44 +0200 Subject: [PATCH 068/237] Add Composite trait --- src/types/entities/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 6f1f58b..bc8273f 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -22,6 +22,8 @@ pub use user_settings::*; pub use voice_state::*; pub use webhook::*; +use crate::gateway::Updateable; + mod application; mod attachment; mod audit_log; @@ -45,3 +47,7 @@ mod user; mod user_settings; mod voice_state; mod webhook; + +pub(crate) trait Composite { + fn watch_whole(self) -> Self; +} From f49fefb400077c7aaf814feef25f1f098ef99215 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 14 Aug 2023 17:18:53 +0200 Subject: [PATCH 069/237] derive Updateable for Guild --- src/types/entities/guild.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index b95b68a..88b55ce 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,9 +1,11 @@ use std::sync::{Arc, RwLock}; +use chorus_macros::Updateable; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; +use crate::gateway::Updateable; use crate::types::types::guild_configuration::GuildFeaturesList; use crate::types::{ entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook}, @@ -12,7 +14,7 @@ use crate::types::{ }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Guild { pub afk_channel_id: Option, From 623c07067173390ce19e5574ec5d26a47c229fe9 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 12:13:49 +0200 Subject: [PATCH 070/237] Add macro and attributes for automatic watching of Composite structs and their components --- chorus-macros/src/lib.rs | 97 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index c8d5e87..7ae2e83 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -1,5 +1,6 @@ use proc_macro::TokenStream; use quote::quote; +use syn::{parse_macro_input, Data, DeriveInput, Field, Fields, FieldsNamed}; #[proc_macro_derive(Updateable)] pub fn updateable_macro_derive(input: TokenStream) -> TokenStream { @@ -16,3 +17,99 @@ pub fn updateable_macro_derive(input: TokenStream) -> TokenStream { } .into() } + +#[proc_macro_attribute] +pub fn observe_option(_args: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn observe_option_vec(_args: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn observe(_args: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn observe_vec(_args: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive( + Composite, + attributes(observe_option_vec, observe_option, observe, observe_vec) +)] +pub fn composite_derive(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + + let process_field = |field: &Field| { + let field_name = &field.ident; + let attrs = &field.attrs; + + let observe_option = attrs + .iter() + .any(|attr| attr.path().is_ident("observe_option")); + let observe_option_vec = attrs + .iter() + .any(|attr| attr.path().is_ident("observe_option_vec")); + let observe = attrs.iter().any(|attr| attr.path().is_ident("observe")); + let observe_vec = attrs.iter().any(|attr| attr.path().is_ident("observe_vec")); + + let field_is_arc_rwlock = if let syn::Type::Path(type_path) = &field.ty { + type_path.path.segments.last().map_or(false, |segment| { + segment.ident == "Arc" || segment.ident == "RwLock" + }) + } else { + false + }; + + if field_is_arc_rwlock { + match (observe_option, observe_option_vec, observe, observe_vec) { + (true, _, _, _) => quote! { + #field_name: option_observe_fn(self.#field_name) + }, + (_, true, _, _) => quote! { + #field_name: option_vec_observe_fn(self.#field_name) + }, + (_, _, true, _) => quote! { + #field_name: value_observe_fn(self.#field_name) + }, + (_, _, _, true) => quote! { + #field_name: vec_observe_fn(self.#field_name) + }, + _ => quote! { + #field_name: self.#field_name + }, + } + } else { + panic!("Fields must be of type Arc>"); + } + }; + + match &input.data { + Data::Struct(data) => match &data.fields { + Fields::Named(FieldsNamed { named, .. }) => { + let field_exprs = named.iter().map(process_field); + + let ident = &input.ident; + + let expanded = quote! { + impl Composite for #ident { + fn watch_whole(self) -> Self { + Self { + #(#field_exprs,)* + } + } + } + }; + + TokenStream::from(expanded) + } + _ => panic!("Composite derive macro only supports named fields"), + }, + _ => panic!("Composite derive macro only supports structs"), + } +} From b2a1122f4a562ae1b5598ebccc0e660a4d386146 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 12:14:03 +0200 Subject: [PATCH 071/237] todo --- src/types/entities/mod.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index bc8273f..aa52ab9 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -23,6 +23,7 @@ pub use voice_state::*; pub use webhook::*; use crate::gateway::Updateable; +use std::sync::{Arc, RwLock}; mod application; mod attachment; @@ -50,4 +51,23 @@ mod webhook; pub(crate) trait Composite { fn watch_whole(self) -> Self; + fn option_observe_fn(value: Option>>) -> Option>> { + // Perform your logic here... + value + } + + fn option_vec_observe_fn(value: Option>>>) -> Option>>> { + // Perform your logic here... + value + } + + fn value_observe_fn(value: Arc>) -> Arc> { + // Perform your logic here... + value + } + + fn vec_observe_fn(value: Vec>>) -> Vec>> { + // Perform your logic here... + value + } } From d0cc1b5a71ed7e5f73b56d9d95a0942c68b5749d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 12:36:53 +0200 Subject: [PATCH 072/237] Update syn dependency --- Cargo.lock | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d193cf4..a58537c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -221,7 +221,7 @@ name = "chorus-macros" version = "0.1.0" dependencies = [ "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -361,7 +361,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -372,7 +372,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -569,7 +569,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1186,7 +1186,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1302,7 +1302,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1683,7 +1683,7 @@ checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1705,7 +1705,7 @@ checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1745,7 +1745,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -1978,9 +1978,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.26" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -2018,7 +2018,7 @@ checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -2102,7 +2102,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -2206,7 +2206,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", ] [[package]] @@ -2384,7 +2384,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -2418,7 +2418,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From ad508153e5554e6e64a0fe1d3ef0a9af7888a6e8 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 16:57:08 +0200 Subject: [PATCH 073/237] Add async-trait --- Cargo.lock | 1 + chorus-macros/Cargo.lock | 12 ++++++++++++ chorus-macros/Cargo.toml | 1 + 3 files changed, 14 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index a58537c..1e8be43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,7 @@ dependencies = [ name = "chorus-macros" version = "0.1.0" dependencies = [ + "async-trait", "quote", "syn 2.0.28", ] diff --git a/chorus-macros/Cargo.lock b/chorus-macros/Cargo.lock index 4aa96d3..0a84f90 100644 --- a/chorus-macros/Cargo.lock +++ b/chorus-macros/Cargo.lock @@ -2,10 +2,22 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "chorus-macros" version = "0.1.0" dependencies = [ + "async-trait", "quote", "syn", ] diff --git a/chorus-macros/Cargo.toml b/chorus-macros/Cargo.toml index cffffe1..dc04a10 100644 --- a/chorus-macros/Cargo.toml +++ b/chorus-macros/Cargo.toml @@ -9,3 +9,4 @@ proc-macro = true [dependencies] quote = "1" syn = "2" +async-trait = "0.1.71" From 28ea95f4a4e98f95f05c8b5468aa6c9d0a7cca54 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 16:57:35 +0200 Subject: [PATCH 074/237] Use async trait where needed --- chorus-macros/src/lib.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index 7ae2e83..554a52d 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -58,27 +58,21 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let observe = attrs.iter().any(|attr| attr.path().is_ident("observe")); let observe_vec = attrs.iter().any(|attr| attr.path().is_ident("observe_vec")); - let field_is_arc_rwlock = if let syn::Type::Path(type_path) = &field.ty { - type_path.path.segments.last().map_or(false, |segment| { - segment.ident == "Arc" || segment.ident == "RwLock" - }) - } else { - false - }; + let field_is_arc_rwlock = true; if field_is_arc_rwlock { match (observe_option, observe_option_vec, observe, observe_vec) { (true, _, _, _) => quote! { - #field_name: option_observe_fn(self.#field_name) + #field_name: Self::option_observe_fn(self.#field_name, gateway).await }, (_, true, _, _) => quote! { - #field_name: option_vec_observe_fn(self.#field_name) + #field_name: Self::option_vec_observe_fn(self.#field_name, gateway).await }, (_, _, true, _) => quote! { - #field_name: value_observe_fn(self.#field_name) + #field_name: Self::value_observe_fn(self.#field_name, gateway).await }, (_, _, _, true) => quote! { - #field_name: vec_observe_fn(self.#field_name) + #field_name: Self::vec_observe_fn(self.#field_name, gateway).await }, _ => quote! { #field_name: self.#field_name @@ -95,10 +89,10 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let field_exprs = named.iter().map(process_field); let ident = &input.ident; - let expanded = quote! { - impl Composite for #ident { - fn watch_whole(self) -> Self { + #[async_trait::async_trait] + impl Composite for #ident { + async fn watch_whole(self, gateway: &GatewayHandle) -> Self { Self { #(#field_exprs,)* } From d66807ed20a9019ab923ea29354362e7c4f8e166 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 16:57:54 +0200 Subject: [PATCH 075/237] Add observe_and_get method --- src/gateway.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/gateway.rs b/src/gateway.rs index 3e0c4f3..dd0fc28 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -223,6 +223,15 @@ impl GatewayHandle { } } + pub async fn observe_and_get( + &self, + object: Arc>, + ) -> Arc> { + let channel = self.observe(object).await; + let object = channel.borrow().clone(); + object + } + /// Sends an identify event to the gateway pub async fn send_identify(&self, to_send: types::GatewayIdentifyPayload) { let to_send_value = serde_json::to_value(&to_send).unwrap(); From 37d976cd0d8119a93fd084b02032b926977d6f3b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 16:58:06 +0200 Subject: [PATCH 076/237] Try out new macro --- src/types/entities/guild.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 88b55ce..ed2be89 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,20 +1,21 @@ use std::sync::{Arc, RwLock}; -use chorus_macros::Updateable; +use chorus_macros::{observe_option_vec, Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::Updateable; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::types::guild_configuration::GuildFeaturesList; use crate::types::{ entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook}, interfaces::WelcomeScreenObject, utils::Snowflake, + Composite, }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Guild { pub afk_channel_id: Option, @@ -29,6 +30,7 @@ pub struct Guild { #[cfg_attr(feature = "sqlx", sqlx(skip))] pub bans: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] + #[observe_option_vec] pub channels: Option>>>, pub default_message_notifications: Option, pub description: Option, From 509ab578d60c455c7bcec20df92d541d9198aebe Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 16:58:20 +0200 Subject: [PATCH 077/237] Implement trait methods --- src/types/entities/mod.rs | 54 ++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index aa52ab9..7a43496 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -22,7 +22,8 @@ pub use user_settings::*; pub use voice_state::*; pub use webhook::*; -use crate::gateway::Updateable; +use crate::gateway::{GatewayHandle, Updateable}; +use async_trait::async_trait; use std::sync::{Arc, RwLock}; mod application; @@ -49,25 +50,48 @@ mod user_settings; mod voice_state; mod webhook; -pub(crate) trait Composite { - fn watch_whole(self) -> Self; - fn option_observe_fn(value: Option>>) -> Option>> { - // Perform your logic here... - value +#[async_trait] +pub(crate) trait Composite { + async fn watch_whole(self, gateway: &GatewayHandle) -> Self; + + async fn option_observe_fn( + value: Option>>, + gateway: &GatewayHandle, + ) -> Option>> { + if let Some(value) = value { + Some(gateway.observe_and_get(value).await) + } else { + None + } } - fn option_vec_observe_fn(value: Option>>>) -> Option>>> { - // Perform your logic here... - value + async fn option_vec_observe_fn( + value: Option>>>, + gateway: &GatewayHandle, + ) -> Option>>> { + if let Some(value) = value { + let mut vec = Vec::new(); + for component in value.into_iter() { + vec.push(gateway.observe_and_get(component).await); + } + Some(vec) + } else { + None + } } - fn value_observe_fn(value: Arc>) -> Arc> { - // Perform your logic here... - value + async fn value_observe_fn(value: Arc>, gateway: &GatewayHandle) -> Arc> { + gateway.observe_and_get(value).await } - fn vec_observe_fn(value: Vec>>) -> Vec>> { - // Perform your logic here... - value + async fn vec_observe_fn( + value: Vec>>, + gateway: &GatewayHandle, + ) -> Vec>> { + let mut vec = Vec::new(); + for component in value.into_iter() { + vec.push(gateway.observe_and_get(component).await); + } + vec } } From 5ac680b64d933258765a109a301db8e78db10808 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 17:08:27 +0200 Subject: [PATCH 078/237] Remove superfluous nesting --- chorus-macros/src/lib.rs | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index 554a52d..c5cc25c 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -58,28 +58,22 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let observe = attrs.iter().any(|attr| attr.path().is_ident("observe")); let observe_vec = attrs.iter().any(|attr| attr.path().is_ident("observe_vec")); - let field_is_arc_rwlock = true; - - if field_is_arc_rwlock { - match (observe_option, observe_option_vec, observe, observe_vec) { - (true, _, _, _) => quote! { - #field_name: Self::option_observe_fn(self.#field_name, gateway).await - }, - (_, true, _, _) => quote! { - #field_name: Self::option_vec_observe_fn(self.#field_name, gateway).await - }, - (_, _, true, _) => quote! { - #field_name: Self::value_observe_fn(self.#field_name, gateway).await - }, - (_, _, _, true) => quote! { - #field_name: Self::vec_observe_fn(self.#field_name, gateway).await - }, - _ => quote! { - #field_name: self.#field_name - }, - } - } else { - panic!("Fields must be of type Arc>"); + match (observe_option, observe_option_vec, observe, observe_vec) { + (true, _, _, _) => quote! { + #field_name: Self::option_observe_fn(self.#field_name, gateway).await + }, + (_, true, _, _) => quote! { + #field_name: Self::option_vec_observe_fn(self.#field_name, gateway).await + }, + (_, _, true, _) => quote! { + #field_name: Self::value_observe_fn(self.#field_name, gateway).await + }, + (_, _, _, true) => quote! { + #field_name: Self::vec_observe_fn(self.#field_name, gateway).await + }, + _ => quote! { + #field_name: self.#field_name + }, } }; From 20baada605308992eccc9a94e5c82b84dbbdbbe1 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 17:38:53 +0200 Subject: [PATCH 079/237] Add Composite to some types --- src/types/entities/channel.rs | 13 ++++++++----- src/types/entities/emoji.rs | 6 ++++-- src/types/entities/guild.rs | 10 +++++++--- src/types/entities/role.rs | 4 +++- src/types/entities/user.rs | 7 +++++-- src/types/entities/voice_state.rs | 6 ++++-- src/types/entities/webhook.rs | 4 +++- 7 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 96cf557..a0c96ed 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -1,18 +1,19 @@ use std::sync::{Arc, RwLock}; -use chorus_macros::Updateable; +use chorus_macros::{observe_option_vec, Composite, Updateable}; use chrono::Utc; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_string_from_number; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::Updateable; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{GuildMember, User}, utils::Snowflake, + Composite, }; -#[derive(Default, Debug, Serialize, Deserialize, Clone, Updateable)] +#[derive(Default, Debug, Serialize, Deserialize, Clone, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// Represents a guild of private channel /// @@ -48,7 +49,7 @@ pub struct Channel { pub last_pin_timestamp: Option, pub managed: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub member: Option>>, + pub member: Option, pub member_count: Option, pub message_count: Option, pub name: Option, @@ -58,11 +59,13 @@ pub struct Channel { #[cfg(feature = "sqlx")] pub permission_overwrites: Option>>, #[cfg(not(feature = "sqlx"))] + #[observe_option_vec] pub permission_overwrites: Option>>>, pub permissions: Option, pub position: Option, pub rate_limit_per_user: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] + #[observe_option_vec] pub recipients: Option>>>, pub rtc_region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] @@ -122,7 +125,7 @@ pub struct Tag { pub emoji_name: Option, } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Updateable)] pub struct PermissionOverwrite { pub id: Snowflake, #[serde(rename = "type")] diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index f96b2b5..8f73091 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -1,16 +1,18 @@ use std::sync::{Arc, RwLock}; +use chorus_macros::Updateable; use serde::{Deserialize, Serialize}; +use crate::gateway::Updateable; use crate::types::entities::User; use crate::types::Snowflake; -#[derive(Debug, Clone, Deserialize, Serialize, Default)] +#[derive(Debug, Clone, Deserialize, Serialize, Default, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See pub struct Emoji { - pub id: Option, + pub id: Snowflake, pub name: Option, #[cfg(feature = "sqlx")] pub roles: Option>>, diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index ed2be89..7f73403 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,6 +1,6 @@ use std::sync::{Arc, RwLock}; -use chorus_macros::{observe_option_vec, Composite, Updateable}; +use chorus_macros::{observe_option_vec, observe_vec, Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -37,6 +37,7 @@ pub struct Guild { pub discovery_splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] #[serde(default)] + #[observe_vec] pub emojis: Vec>>, pub explicit_content_filter: Option, //#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))] @@ -46,7 +47,7 @@ pub struct Guild { pub icon_hash: Option, pub id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub invites: Option>>>, + pub invites: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub joined_at: Option, pub large: Option, @@ -72,6 +73,7 @@ pub struct Guild { pub public_updates_channel_id: Option, pub region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] + #[observe_option_vec] pub roles: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub rules_channel: Option, @@ -85,13 +87,15 @@ pub struct Guild { pub vanity_url_code: Option, pub verification_level: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] + #[observe_option_vec] pub voice_states: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] + #[observe_option_vec] pub webhooks: Option>>>, #[cfg(feature = "sqlx")] pub welcome_screen: Option>, #[cfg(not(feature = "sqlx"))] - pub welcome_screen: Option>>, + pub welcome_screen: Option, pub widget_channel_id: Option, pub widget_enabled: Option, } diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 3ad53ce..7ca9597 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -1,10 +1,12 @@ use bitflags::bitflags; +use chorus_macros::Updateable; use serde::{Deserialize, Serialize}; use serde_aux::prelude::{deserialize_option_number_from_string, deserialize_string_from_number}; +use crate::gateway::Updateable; use crate::types::utils::Snowflake; -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// See pub struct RoleObject { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 5b31b6d..9382ccb 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -1,8 +1,11 @@ -use crate::types::utils::Snowflake; +use chorus_macros::Updateable; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; +use crate::gateway::Updateable; +use crate::types::utils::Snowflake; + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] pub struct UserData { @@ -15,7 +18,7 @@ impl User { PublicUser::from(self) } } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct User { pub id: Snowflake, diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index 9f6a2c0..9988162 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -1,15 +1,17 @@ use std::sync::{Arc, RwLock}; +use chorus_macros::Updateable; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use crate::gateway::Updateable; use crate::types::{ entities::{Guild, GuildMember}, utils::Snowflake, }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct VoiceState { pub guild_id: Option, @@ -27,5 +29,5 @@ pub struct VoiceState { pub self_video: bool, pub suppress: bool, pub request_to_speak_timestamp: Option>, - pub id: Option, + pub id: Snowflake, } diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index 079f584..f6710bd 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -1,14 +1,16 @@ use std::sync::{Arc, RwLock}; +use chorus_macros::Updateable; use serde::{Deserialize, Serialize}; +use crate::gateway::Updateable; use crate::types::{ entities::{Guild, User}, utils::Snowflake, }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Webhook { pub id: Snowflake, From 7de3204f5921f0faf9444e50900242f1bab7a07f Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 17:54:36 +0200 Subject: [PATCH 080/237] Make trait pub --- src/types/entities/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 7a43496..1331c9c 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -51,7 +51,7 @@ mod voice_state; mod webhook; #[async_trait] -pub(crate) trait Composite { +pub trait Composite { async fn watch_whole(self, gateway: &GatewayHandle) -> Self; async fn option_observe_fn( From c3be91667be31cfcd5a954e073af46ddfcdb3d53 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 17:54:48 +0200 Subject: [PATCH 081/237] Try calling new method to see if it panics --- tests/gateway.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 2a9e38c..10ae04d 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,7 @@ mod common; use chorus::gateway::*; -use chorus::types::{self, Channel, ChannelModifySchema}; +use chorus::types::{self, Channel, ChannelModifySchema, Composite}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -31,7 +31,10 @@ async fn test_self_updating_structs() { let mut bundle = common::setup().await; let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; let received_channel = channel_updater.borrow().clone().read().unwrap().clone(); + let something = + Composite::::watch_whole(received_channel.clone(), &bundle.user.gateway); assert_eq!(received_channel, bundle.channel.read().unwrap().clone()); + drop(something); let updater = bundle.user.gateway.observe(bundle.channel.clone()).await; assert_eq!( From 32fd918a43281aa332c6683e50d2649fbd9f8fa2 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 20:18:11 +0200 Subject: [PATCH 082/237] Remove `Send` bound --- chorus-macros/src/lib.rs | 2 +- src/types/entities/mod.rs | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index c5cc25c..72e5ddd 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -84,7 +84,7 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let ident = &input.ident; let expanded = quote! { - #[async_trait::async_trait] + #[async_trait::async_trait(?Send)] impl Composite for #ident { async fn watch_whole(self, gateway: &GatewayHandle) -> Self { Self { diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 1331c9c..7f8cc56 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -50,15 +50,19 @@ mod user_settings; mod voice_state; mod webhook; -#[async_trait] +#[async_trait(?Send)] pub trait Composite { async fn watch_whole(self, gateway: &GatewayHandle) -> Self; async fn option_observe_fn( value: Option>>, gateway: &GatewayHandle, - ) -> Option>> { + ) -> Option>> + where + T: Composite, + { if let Some(value) = value { + let value = value.clone(); Some(gateway.observe_and_get(value).await) } else { None @@ -68,7 +72,10 @@ pub trait Composite { async fn option_vec_observe_fn( value: Option>>>, gateway: &GatewayHandle, - ) -> Option>>> { + ) -> Option>>> + where + T: Composite, + { if let Some(value) = value { let mut vec = Vec::new(); for component in value.into_iter() { @@ -80,14 +87,20 @@ pub trait Composite { } } - async fn value_observe_fn(value: Arc>, gateway: &GatewayHandle) -> Arc> { + async fn value_observe_fn(value: Arc>, gateway: &GatewayHandle) -> Arc> + where + T: Composite, + { gateway.observe_and_get(value).await } async fn vec_observe_fn( value: Vec>>, gateway: &GatewayHandle, - ) -> Vec>> { + ) -> Vec>> + where + T: Composite, + { let mut vec = Vec::new(); for component in value.into_iter() { vec.push(gateway.observe_and_get(component).await); From bdeaa476e2d6461e3e8357f561ed4d69ff031331 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 20:19:16 +0200 Subject: [PATCH 083/237] Add `Composite` bound to automatically call `watch_whole()` on caller object. --- src/gateway.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index dd0fc28..886bd3a 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -1,6 +1,6 @@ use crate::errors::GatewayError; use crate::gateway::events::Events; -use crate::types::{self, Channel, ChannelUpdate, Snowflake}; +use crate::types::{self, Channel, ChannelUpdate, Composite, Snowflake}; use crate::types::{UpdateMessage, WebSocketEvent}; use async_trait::async_trait; use std::any::Any; @@ -196,12 +196,13 @@ impl GatewayHandle { .unwrap(); } - pub async fn observe( + pub async fn observe>( &self, object: Arc>, ) -> watch::Receiver>> { let mut store = self.store.lock().await; - if let Some(channel) = store.get(&object.clone().read().unwrap().id()) { + let id = object.read().unwrap().id(); + if let Some(channel) = store.get(&id) { let (_, rx) = channel .downcast_ref::<( watch::Sender>>, @@ -216,18 +217,20 @@ impl GatewayHandle { rx.clone() } else { let id = object.read().unwrap().id(); - let channel = watch::channel(object); + let object = object.read().unwrap().clone(); + let object = object.clone().watch_whole(self).await; + let channel = watch::channel(Arc::new(RwLock::new(object))); let receiver = channel.1.clone(); store.insert(id, Box::new(channel)); receiver } } - pub async fn observe_and_get( + pub async fn observe_and_get>( &self, object: Arc>, ) -> Arc> { - let channel = self.observe(object).await; + let channel = self.observe(object.clone()).await; let object = channel.borrow().clone(); object } From ff77e5a61dc3362dceff897ed76e06806f2cdb33 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 20:19:52 +0200 Subject: [PATCH 084/237] Add `Composite` derive to all entities which require it --- src/types/entities/channel.rs | 4 +++- src/types/entities/emoji.rs | 8 ++++---- src/types/entities/role.rs | 8 ++++---- src/types/entities/user.rs | 8 ++++---- src/types/entities/voice_state.rs | 7 ++++--- src/types/entities/webhook.rs | 7 ++++--- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index a0c96ed..ad776d8 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -125,7 +125,9 @@ pub struct Tag { pub emoji_name: Option, } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Updateable)] +#[derive( + Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Updateable, Composite, +)] pub struct PermissionOverwrite { pub id: Snowflake, #[serde(rename = "type")] diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 8f73091..308c41b 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -1,13 +1,13 @@ use std::sync::{Arc, RwLock}; -use chorus_macros::Updateable; +use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::Updateable; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::entities::User; -use crate::types::Snowflake; +use crate::types::{Composite, Snowflake}; -#[derive(Debug, Clone, Deserialize, Serialize, Default, Updateable)] +#[derive(Debug, Clone, Deserialize, Serialize, Default, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 7ca9597..9fac835 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -1,12 +1,12 @@ use bitflags::bitflags; -use chorus_macros::Updateable; +use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::{deserialize_option_number_from_string, deserialize_string_from_number}; -use crate::gateway::Updateable; -use crate::types::utils::Snowflake; +use crate::gateway::{GatewayHandle, Updateable}; +use crate::types::{utils::Snowflake, Composite}; -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Updateable)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// See pub struct RoleObject { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 9382ccb..56329b2 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -1,10 +1,10 @@ -use chorus_macros::Updateable; +use chorus_macros::{Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; -use crate::gateway::Updateable; -use crate::types::utils::Snowflake; +use crate::gateway::{GatewayHandle, Updateable}; +use crate::types::{utils::Snowflake, Composite}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] @@ -18,7 +18,7 @@ impl User { PublicUser::from(self) } } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Updateable)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct User { pub id: Snowflake, diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index 9988162..e74aa7d 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -1,17 +1,18 @@ use std::sync::{Arc, RwLock}; -use chorus_macros::Updateable; +use chorus_macros::{Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use crate::gateway::Updateable; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{Guild, GuildMember}, utils::Snowflake, + Composite, }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct VoiceState { pub guild_id: Option, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index f6710bd..dd88ca1 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -1,16 +1,17 @@ use std::sync::{Arc, RwLock}; -use chorus_macros::Updateable; +use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::Updateable; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{Guild, User}, utils::Snowflake, + Composite, }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Webhook { pub id: Snowflake, From c03b250248fe67ce02319c3ab0810b593441c4ee Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 20:20:58 +0200 Subject: [PATCH 085/237] Clean up test --- tests/gateway.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 10ae04d..3196f7c 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -31,10 +31,8 @@ async fn test_self_updating_structs() { let mut bundle = common::setup().await; let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; let received_channel = channel_updater.borrow().clone().read().unwrap().clone(); - let something = - Composite::::watch_whole(received_channel.clone(), &bundle.user.gateway); + assert_eq!(received_channel, bundle.channel.read().unwrap().clone()); - drop(something); let updater = bundle.user.gateway.observe(bundle.channel.clone()).await; assert_eq!( From 2fd1a7e7f48deb7c89d49ccb4e4c8013b54bc9da Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 20:30:30 +0200 Subject: [PATCH 086/237] Remove unused import --- tests/gateway.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 3196f7c..4cc450a 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,7 @@ mod common; use chorus::gateway::*; -use chorus::types::{self, Channel, ChannelModifySchema, Composite}; +use chorus::types::{self, Channel, ChannelModifySchema}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; From 2b21933cb3245b763dba2a6ff3d43a4b283cbb46 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 22:19:47 +0200 Subject: [PATCH 087/237] Add back set_json. No idea when it disappeared? --- src/gateway.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 3fb56e7..9232c2d 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -1,7 +1,8 @@ use crate::errors::GatewayError; use crate::gateway::events::Events; -use crate::types::{self, Channel, ChannelUpdate, Composite, Snowflake}; -use crate::types::{UpdateMessage, WebSocketEvent}; +use crate::types::{ + self, Channel, ChannelUpdate, Composite, JsonField, Snowflake, UpdateMessage, WebSocketEvent, +}; use async_trait::async_trait; use std::any::Any; use std::collections::HashMap; @@ -496,7 +497,8 @@ impl Gateway { match event_name.as_str() { $($name => { let event = &mut self.events.lock().await.$($path).+; - match serde_json::from_str(gateway_payload.event_data.unwrap().get()) { + let json = gateway_payload.event_data.unwrap().get(); + match serde_json::from_str(json) { Err(err) => warn!("Failed to parse gateway event {event_name} ({err})"), Ok(message) => { $( @@ -506,6 +508,7 @@ impl Gateway { // `object` is the current value of the `watch::channel`. It's being passed into `message.update()` to be modified // within the closure function. Then, this closure is passed to the `tx.send_modify()` method which applies the // modification to the current value of the watch channel. + message.set_json(json.to_string()); tx.send_modify(|object| message.update(object.clone())); } else { warn!("Received {} for {}, but it has been observed to be a different type!", $name, message.id()) From 8087dd69c839fd250ca1532b6abeb472d5ce1acc Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 15 Aug 2023 23:41:42 +0200 Subject: [PATCH 088/237] Give `GatewayHandle` and `Gateway` common trait to call `watch_whole()` or observe() from a `Gateway` --- chorus-macros/src/lib.rs | 2 +- src/gateway.rs | 77 +++++++++++++++++++++---------- src/types/entities/channel.rs | 2 +- src/types/entities/emoji.rs | 2 +- src/types/entities/guild.rs | 2 +- src/types/entities/mod.rs | 15 +++--- src/types/entities/role.rs | 2 +- src/types/entities/user.rs | 2 +- src/types/entities/voice_state.rs | 2 +- src/types/entities/webhook.rs | 2 +- src/types/events/guild.rs | 29 ++++++++++-- tests/gateway.rs | 5 +- 12 files changed, 99 insertions(+), 43 deletions(-) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index baac40b..50bcebf 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -105,7 +105,7 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let expanded = quote! { #[async_trait::async_trait(?Send)] impl Composite for #ident { - async fn watch_whole(self, gateway: &GatewayHandle) -> Self { + async fn watch_whole(self, gateway: &(impl GatewayObject + ?Sized)) -> Self { Self { #(#field_exprs,)* } diff --git a/src/gateway.rs b/src/gateway.rs index 9232c2d..950ec96 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -180,32 +180,16 @@ pub trait Updateable: 'static + Send + Sync { fn id(&self) -> Snowflake; } -impl GatewayHandle { - /// Sends json to the gateway with an opcode - async fn send_json_event(&self, op_code: u8, to_send: serde_json::Value) { - let gateway_payload = types::GatewaySendPayload { - op_code, - event_data: Some(to_send), - sequence_number: None, - }; - - let payload_json = serde_json::to_string(&gateway_payload).unwrap(); - - let message = tokio_tungstenite::tungstenite::Message::text(payload_json); - - self.websocket_send - .lock() - .await - .send(message) - .await - .unwrap(); - } - - pub async fn observe>( +#[async_trait(?Send)] +pub trait GatewayObject { + fn store(&self) -> Arc>>>; + fn events(&self) -> Arc>; + async fn observe>( &self, object: Arc>, ) -> watch::Receiver>> { - let mut store = self.store.lock().await; + let store = self.store(); + let mut store = store.lock().await; let id = object.read().unwrap().id(); if let Some(channel) = store.get(&id) { let (_, rx) = channel @@ -230,8 +214,7 @@ impl GatewayHandle { receiver } } - - pub async fn observe_and_get>( + async fn observe_and_get>( &self, object: Arc>, ) -> Arc> { @@ -239,6 +222,50 @@ impl GatewayHandle { let object = channel.borrow().clone(); object } +} + +#[async_trait(?Send)] +impl GatewayObject for GatewayHandle { + fn store(&self) -> Arc>>> { + self.store.clone() + } + + fn events(&self) -> Arc> { + self.events.clone() + } +} + +#[async_trait(?Send)] +impl GatewayObject for Gateway { + fn store(&self) -> Arc>>> { + self.store.clone() + } + + fn events(&self) -> Arc> { + self.events.clone() + } +} + +impl GatewayHandle { + /// Sends json to the gateway with an opcode + async fn send_json_event(&self, op_code: u8, to_send: serde_json::Value) { + let gateway_payload = types::GatewaySendPayload { + op_code, + event_data: Some(to_send), + sequence_number: None, + }; + + let payload_json = serde_json::to_string(&gateway_payload).unwrap(); + + let message = tokio_tungstenite::tungstenite::Message::text(payload_json); + + self.websocket_send + .lock() + .await + .send(message) + .await + .unwrap(); + } /// Sends an identify event to the gateway pub async fn send_identify(&self, to_send: types::GatewayIdentifyPayload) { diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index ad776d8..8f0bf8b 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_string_from_number; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{ entities::{GuildMember, User}, utils::Snowflake, diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 308c41b..25b7d9a 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::entities::User; use crate::types::{Composite, Snowflake}; diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 7f73403..8f875ec 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -5,7 +5,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::types::guild_configuration::GuildFeaturesList; use crate::types::{ entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook}, diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 7f8cc56..a92463c 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -22,7 +22,7 @@ pub use user_settings::*; pub use voice_state::*; pub use webhook::*; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use async_trait::async_trait; use std::sync::{Arc, RwLock}; @@ -52,11 +52,11 @@ mod webhook; #[async_trait(?Send)] pub trait Composite { - async fn watch_whole(self, gateway: &GatewayHandle) -> Self; + async fn watch_whole(self, gateway: &(impl GatewayObject + ?Sized)) -> Self; async fn option_observe_fn( value: Option>>, - gateway: &GatewayHandle, + gateway: &(impl GatewayObject + ?Sized), ) -> Option>> where T: Composite, @@ -71,7 +71,7 @@ pub trait Composite { async fn option_vec_observe_fn( value: Option>>>, - gateway: &GatewayHandle, + gateway: &(impl GatewayObject + ?Sized), ) -> Option>>> where T: Composite, @@ -87,7 +87,10 @@ pub trait Composite { } } - async fn value_observe_fn(value: Arc>, gateway: &GatewayHandle) -> Arc> + async fn value_observe_fn( + value: Arc>, + gateway: &(impl GatewayObject + ?Sized), + ) -> Arc> where T: Composite, { @@ -96,7 +99,7 @@ pub trait Composite { async fn vec_observe_fn( value: Vec>>, - gateway: &GatewayHandle, + gateway: &(impl GatewayObject + ?Sized), ) -> Vec>> where T: Composite, diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 9fac835..17b9024 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -3,7 +3,7 @@ use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::{deserialize_option_number_from_string, deserialize_string_from_number}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{utils::Snowflake, Composite}; #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Updateable, Composite)] diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 56329b2..22e3e9c 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -3,7 +3,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{utils::Snowflake, Composite}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index e74aa7d..798fe04 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -4,7 +4,7 @@ use chorus_macros::{Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{ entities::{Guild, GuildMember}, utils::Snowflake, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index dd88ca1..c80cdbd 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{ entities::{Guild, User}, utils::Snowflake, diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 2cbdbd0..89a8339 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -1,13 +1,17 @@ +use std::sync::{Arc, RwLock}; + +use chorus_macros::JsonField; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::types::entities::{Guild, PublicUser, UnavailableGuild}; use crate::types::events::WebSocketEvent; use crate::types::{ - AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, RoleObject, Snowflake, Sticker, + AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, JsonField, RoleObject, Snowflake, + Sticker, }; -use super::PresenceUpdate; +use super::{PresenceUpdate, UpdateMessage}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// See ; @@ -164,15 +168,34 @@ pub struct GuildMembersChunk { impl WebSocketEvent for GuildMembersChunk {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct GuildRoleCreate { pub guild_id: Snowflake, pub role: RoleObject, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for GuildRoleCreate {} +impl UpdateMessage for GuildRoleCreate { + fn id(&self) -> Snowflake { + self.role.id + } + + fn update(&mut self, object_to_update: std::sync::Arc>) { + let mut write = object_to_update.write().unwrap(); + if write.roles.is_some() { + write + .roles + .as_mut() + .unwrap() + .push(Arc::new(RwLock::new(self.role.clone()))); + } + } +} + #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See pub struct GuildRoleUpdate { diff --git a/tests/gateway.rs b/tests/gateway.rs index 4cc450a..742dc4e 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,7 @@ mod common; use chorus::gateway::*; -use chorus::types::{self, Channel, ChannelModifySchema}; +use chorus::types::{self, Channel, ChannelModifySchema, Guild}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -63,3 +63,6 @@ async fn test_self_updating_structs() { common::teardown(bundle).await } + +#[tokio::test] +async fn test_recursive_self_updating_structs() {} From d36b1de1700610b86afd1c52d20b9d0699c8be12 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 00:18:32 +0200 Subject: [PATCH 089/237] Give `GatewayHandle` and `Gateway` common trait to call `watch_whole()` or observe() from a `Gateway` --- chorus-macros/src/lib.rs | 2 +- src/gateway.rs | 77 +++++++++++++++++++++---------- src/types/entities/channel.rs | 2 +- src/types/entities/emoji.rs | 2 +- src/types/entities/guild.rs | 2 +- src/types/entities/mod.rs | 15 +++--- src/types/entities/role.rs | 2 +- src/types/entities/user.rs | 2 +- src/types/entities/voice_state.rs | 2 +- src/types/entities/webhook.rs | 2 +- src/types/events/guild.rs | 29 ++++++++++-- tests/gateway.rs | 5 +- 12 files changed, 99 insertions(+), 43 deletions(-) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index baac40b..50bcebf 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -105,7 +105,7 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let expanded = quote! { #[async_trait::async_trait(?Send)] impl Composite for #ident { - async fn watch_whole(self, gateway: &GatewayHandle) -> Self { + async fn watch_whole(self, gateway: &(impl GatewayObject + ?Sized)) -> Self { Self { #(#field_exprs,)* } diff --git a/src/gateway.rs b/src/gateway.rs index 9232c2d..950ec96 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -180,32 +180,16 @@ pub trait Updateable: 'static + Send + Sync { fn id(&self) -> Snowflake; } -impl GatewayHandle { - /// Sends json to the gateway with an opcode - async fn send_json_event(&self, op_code: u8, to_send: serde_json::Value) { - let gateway_payload = types::GatewaySendPayload { - op_code, - event_data: Some(to_send), - sequence_number: None, - }; - - let payload_json = serde_json::to_string(&gateway_payload).unwrap(); - - let message = tokio_tungstenite::tungstenite::Message::text(payload_json); - - self.websocket_send - .lock() - .await - .send(message) - .await - .unwrap(); - } - - pub async fn observe>( +#[async_trait(?Send)] +pub trait GatewayObject { + fn store(&self) -> Arc>>>; + fn events(&self) -> Arc>; + async fn observe>( &self, object: Arc>, ) -> watch::Receiver>> { - let mut store = self.store.lock().await; + let store = self.store(); + let mut store = store.lock().await; let id = object.read().unwrap().id(); if let Some(channel) = store.get(&id) { let (_, rx) = channel @@ -230,8 +214,7 @@ impl GatewayHandle { receiver } } - - pub async fn observe_and_get>( + async fn observe_and_get>( &self, object: Arc>, ) -> Arc> { @@ -239,6 +222,50 @@ impl GatewayHandle { let object = channel.borrow().clone(); object } +} + +#[async_trait(?Send)] +impl GatewayObject for GatewayHandle { + fn store(&self) -> Arc>>> { + self.store.clone() + } + + fn events(&self) -> Arc> { + self.events.clone() + } +} + +#[async_trait(?Send)] +impl GatewayObject for Gateway { + fn store(&self) -> Arc>>> { + self.store.clone() + } + + fn events(&self) -> Arc> { + self.events.clone() + } +} + +impl GatewayHandle { + /// Sends json to the gateway with an opcode + async fn send_json_event(&self, op_code: u8, to_send: serde_json::Value) { + let gateway_payload = types::GatewaySendPayload { + op_code, + event_data: Some(to_send), + sequence_number: None, + }; + + let payload_json = serde_json::to_string(&gateway_payload).unwrap(); + + let message = tokio_tungstenite::tungstenite::Message::text(payload_json); + + self.websocket_send + .lock() + .await + .send(message) + .await + .unwrap(); + } /// Sends an identify event to the gateway pub async fn send_identify(&self, to_send: types::GatewayIdentifyPayload) { diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index ad776d8..8f0bf8b 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_string_from_number; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{ entities::{GuildMember, User}, utils::Snowflake, diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 308c41b..25b7d9a 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::entities::User; use crate::types::{Composite, Snowflake}; diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 7f73403..8f875ec 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -5,7 +5,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::types::guild_configuration::GuildFeaturesList; use crate::types::{ entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook}, diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 7f8cc56..a92463c 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -22,7 +22,7 @@ pub use user_settings::*; pub use voice_state::*; pub use webhook::*; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use async_trait::async_trait; use std::sync::{Arc, RwLock}; @@ -52,11 +52,11 @@ mod webhook; #[async_trait(?Send)] pub trait Composite { - async fn watch_whole(self, gateway: &GatewayHandle) -> Self; + async fn watch_whole(self, gateway: &(impl GatewayObject + ?Sized)) -> Self; async fn option_observe_fn( value: Option>>, - gateway: &GatewayHandle, + gateway: &(impl GatewayObject + ?Sized), ) -> Option>> where T: Composite, @@ -71,7 +71,7 @@ pub trait Composite { async fn option_vec_observe_fn( value: Option>>>, - gateway: &GatewayHandle, + gateway: &(impl GatewayObject + ?Sized), ) -> Option>>> where T: Composite, @@ -87,7 +87,10 @@ pub trait Composite { } } - async fn value_observe_fn(value: Arc>, gateway: &GatewayHandle) -> Arc> + async fn value_observe_fn( + value: Arc>, + gateway: &(impl GatewayObject + ?Sized), + ) -> Arc> where T: Composite, { @@ -96,7 +99,7 @@ pub trait Composite { async fn vec_observe_fn( value: Vec>>, - gateway: &GatewayHandle, + gateway: &(impl GatewayObject + ?Sized), ) -> Vec>> where T: Composite, diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 9fac835..17b9024 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -3,7 +3,7 @@ use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::{deserialize_option_number_from_string, deserialize_string_from_number}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{utils::Snowflake, Composite}; #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Updateable, Composite)] diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 56329b2..22e3e9c 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -3,7 +3,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{utils::Snowflake, Composite}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index e74aa7d..798fe04 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -4,7 +4,7 @@ use chorus_macros::{Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{ entities::{Guild, GuildMember}, utils::Snowflake, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index dd88ca1..c80cdbd 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayHandle, Updateable}; +use crate::gateway::{GatewayObject, Updateable}; use crate::types::{ entities::{Guild, User}, utils::Snowflake, diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 2cbdbd0..89a8339 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -1,13 +1,17 @@ +use std::sync::{Arc, RwLock}; + +use chorus_macros::JsonField; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::types::entities::{Guild, PublicUser, UnavailableGuild}; use crate::types::events::WebSocketEvent; use crate::types::{ - AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, RoleObject, Snowflake, Sticker, + AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, JsonField, RoleObject, Snowflake, + Sticker, }; -use super::PresenceUpdate; +use super::{PresenceUpdate, UpdateMessage}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// See ; @@ -164,15 +168,34 @@ pub struct GuildMembersChunk { impl WebSocketEvent for GuildMembersChunk {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct GuildRoleCreate { pub guild_id: Snowflake, pub role: RoleObject, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for GuildRoleCreate {} +impl UpdateMessage for GuildRoleCreate { + fn id(&self) -> Snowflake { + self.role.id + } + + fn update(&mut self, object_to_update: std::sync::Arc>) { + let mut write = object_to_update.write().unwrap(); + if write.roles.is_some() { + write + .roles + .as_mut() + .unwrap() + .push(Arc::new(RwLock::new(self.role.clone()))); + } + } +} + #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See pub struct GuildRoleUpdate { diff --git a/tests/gateway.rs b/tests/gateway.rs index 4cc450a..742dc4e 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,7 @@ mod common; use chorus::gateway::*; -use chorus::types::{self, Channel, ChannelModifySchema}; +use chorus::types::{self, Channel, ChannelModifySchema, Guild}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -63,3 +63,6 @@ async fn test_self_updating_structs() { common::teardown(bundle).await } + +#[tokio::test] +async fn test_recursive_self_updating_structs() {} From a9381fec1e60fc350dd6c8e7c92e9e2c7c207d95 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 00:21:18 +0200 Subject: [PATCH 090/237] Revert "Give `GatewayHandle` and `Gateway` common trait to call `watch_whole()` or observe() from a `Gateway`" This reverts commit d36b1de1700610b86afd1c52d20b9d0699c8be12. --- chorus-macros/src/lib.rs | 2 +- src/gateway.rs | 77 ++++++++++--------------------- src/types/entities/channel.rs | 2 +- src/types/entities/emoji.rs | 2 +- src/types/entities/guild.rs | 2 +- src/types/entities/mod.rs | 15 +++--- src/types/entities/role.rs | 2 +- src/types/entities/user.rs | 2 +- src/types/entities/voice_state.rs | 2 +- src/types/entities/webhook.rs | 2 +- src/types/events/guild.rs | 29 ++---------- tests/gateway.rs | 5 +- 12 files changed, 43 insertions(+), 99 deletions(-) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index 50bcebf..baac40b 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -105,7 +105,7 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let expanded = quote! { #[async_trait::async_trait(?Send)] impl Composite for #ident { - async fn watch_whole(self, gateway: &(impl GatewayObject + ?Sized)) -> Self { + async fn watch_whole(self, gateway: &GatewayHandle) -> Self { Self { #(#field_exprs,)* } diff --git a/src/gateway.rs b/src/gateway.rs index 950ec96..9232c2d 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -180,16 +180,32 @@ pub trait Updateable: 'static + Send + Sync { fn id(&self) -> Snowflake; } -#[async_trait(?Send)] -pub trait GatewayObject { - fn store(&self) -> Arc>>>; - fn events(&self) -> Arc>; - async fn observe>( +impl GatewayHandle { + /// Sends json to the gateway with an opcode + async fn send_json_event(&self, op_code: u8, to_send: serde_json::Value) { + let gateway_payload = types::GatewaySendPayload { + op_code, + event_data: Some(to_send), + sequence_number: None, + }; + + let payload_json = serde_json::to_string(&gateway_payload).unwrap(); + + let message = tokio_tungstenite::tungstenite::Message::text(payload_json); + + self.websocket_send + .lock() + .await + .send(message) + .await + .unwrap(); + } + + pub async fn observe>( &self, object: Arc>, ) -> watch::Receiver>> { - let store = self.store(); - let mut store = store.lock().await; + let mut store = self.store.lock().await; let id = object.read().unwrap().id(); if let Some(channel) = store.get(&id) { let (_, rx) = channel @@ -214,7 +230,8 @@ pub trait GatewayObject { receiver } } - async fn observe_and_get>( + + pub async fn observe_and_get>( &self, object: Arc>, ) -> Arc> { @@ -222,50 +239,6 @@ pub trait GatewayObject { let object = channel.borrow().clone(); object } -} - -#[async_trait(?Send)] -impl GatewayObject for GatewayHandle { - fn store(&self) -> Arc>>> { - self.store.clone() - } - - fn events(&self) -> Arc> { - self.events.clone() - } -} - -#[async_trait(?Send)] -impl GatewayObject for Gateway { - fn store(&self) -> Arc>>> { - self.store.clone() - } - - fn events(&self) -> Arc> { - self.events.clone() - } -} - -impl GatewayHandle { - /// Sends json to the gateway with an opcode - async fn send_json_event(&self, op_code: u8, to_send: serde_json::Value) { - let gateway_payload = types::GatewaySendPayload { - op_code, - event_data: Some(to_send), - sequence_number: None, - }; - - let payload_json = serde_json::to_string(&gateway_payload).unwrap(); - - let message = tokio_tungstenite::tungstenite::Message::text(payload_json); - - self.websocket_send - .lock() - .await - .send(message) - .await - .unwrap(); - } /// Sends an identify event to the gateway pub async fn send_identify(&self, to_send: types::GatewayIdentifyPayload) { diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 8f0bf8b..ad776d8 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_string_from_number; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{GuildMember, User}, utils::Snowflake, diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 25b7d9a..308c41b 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::entities::User; use crate::types::{Composite, Snowflake}; diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 8f875ec..7f73403 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -5,7 +5,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::types::guild_configuration::GuildFeaturesList; use crate::types::{ entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook}, diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index a92463c..7f8cc56 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -22,7 +22,7 @@ pub use user_settings::*; pub use voice_state::*; pub use webhook::*; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use async_trait::async_trait; use std::sync::{Arc, RwLock}; @@ -52,11 +52,11 @@ mod webhook; #[async_trait(?Send)] pub trait Composite { - async fn watch_whole(self, gateway: &(impl GatewayObject + ?Sized)) -> Self; + async fn watch_whole(self, gateway: &GatewayHandle) -> Self; async fn option_observe_fn( value: Option>>, - gateway: &(impl GatewayObject + ?Sized), + gateway: &GatewayHandle, ) -> Option>> where T: Composite, @@ -71,7 +71,7 @@ pub trait Composite { async fn option_vec_observe_fn( value: Option>>>, - gateway: &(impl GatewayObject + ?Sized), + gateway: &GatewayHandle, ) -> Option>>> where T: Composite, @@ -87,10 +87,7 @@ pub trait Composite { } } - async fn value_observe_fn( - value: Arc>, - gateway: &(impl GatewayObject + ?Sized), - ) -> Arc> + async fn value_observe_fn(value: Arc>, gateway: &GatewayHandle) -> Arc> where T: Composite, { @@ -99,7 +96,7 @@ pub trait Composite { async fn vec_observe_fn( value: Vec>>, - gateway: &(impl GatewayObject + ?Sized), + gateway: &GatewayHandle, ) -> Vec>> where T: Composite, diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 17b9024..9fac835 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -3,7 +3,7 @@ use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::{deserialize_option_number_from_string, deserialize_string_from_number}; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{utils::Snowflake, Composite}; #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Updateable, Composite)] diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 22e3e9c..56329b2 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -3,7 +3,7 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{utils::Snowflake, Composite}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index 798fe04..e74aa7d 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -4,7 +4,7 @@ use chorus_macros::{Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{Guild, GuildMember}, utils::Snowflake, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index c80cdbd..dd88ca1 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayObject, Updateable}; +use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{Guild, User}, utils::Snowflake, diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 89a8339..2cbdbd0 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -1,17 +1,13 @@ -use std::sync::{Arc, RwLock}; - -use chorus_macros::JsonField; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::types::entities::{Guild, PublicUser, UnavailableGuild}; use crate::types::events::WebSocketEvent; use crate::types::{ - AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, JsonField, RoleObject, Snowflake, - Sticker, + AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, RoleObject, Snowflake, Sticker, }; -use super::{PresenceUpdate, UpdateMessage}; +use super::PresenceUpdate; #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// See ; @@ -168,34 +164,15 @@ pub struct GuildMembersChunk { impl WebSocketEvent for GuildMembersChunk {} -#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] +#[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See pub struct GuildRoleCreate { pub guild_id: Snowflake, pub role: RoleObject, - #[serde(skip)] - pub json: String, } impl WebSocketEvent for GuildRoleCreate {} -impl UpdateMessage for GuildRoleCreate { - fn id(&self) -> Snowflake { - self.role.id - } - - fn update(&mut self, object_to_update: std::sync::Arc>) { - let mut write = object_to_update.write().unwrap(); - if write.roles.is_some() { - write - .roles - .as_mut() - .unwrap() - .push(Arc::new(RwLock::new(self.role.clone()))); - } - } -} - #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See pub struct GuildRoleUpdate { diff --git a/tests/gateway.rs b/tests/gateway.rs index 742dc4e..4cc450a 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,7 @@ mod common; use chorus::gateway::*; -use chorus::types::{self, Channel, ChannelModifySchema, Guild}; +use chorus::types::{self, Channel, ChannelModifySchema}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -63,6 +63,3 @@ async fn test_self_updating_structs() { common::teardown(bundle).await } - -#[tokio::test] -async fn test_recursive_self_updating_structs() {} From 5f0f19e8ce2dcba09e04af421db0348a1643cfeb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 01:11:26 +0200 Subject: [PATCH 091/237] Rename functions, add observe_and_into_inner --- src/gateway.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 9232c2d..a39cb0f 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -201,7 +201,7 @@ impl GatewayHandle { .unwrap(); } - pub async fn observe>( + pub async fn observer_channel>( &self, object: Arc>, ) -> watch::Receiver>> { @@ -235,11 +235,20 @@ impl GatewayHandle { &self, object: Arc>, ) -> Arc> { - let channel = self.observe(object.clone()).await; + let channel = self.observer_channel(object.clone()).await; let object = channel.borrow().clone(); object } + pub async fn observe_and_into_inner>( + &self, + object: Arc>, + ) -> T { + let channel = self.observer_channel(object.clone()).await; + let object = channel.borrow().clone().read().unwrap().clone(); + object + } + /// Sends an identify event to the gateway pub async fn send_identify(&self, to_send: types::GatewayIdentifyPayload) { let to_send_value = serde_json::to_value(&to_send).unwrap(); From e43fe061b35da0c2e6f0e14c319766c43dd38559 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 01:11:32 +0200 Subject: [PATCH 092/237] Refactor test --- tests/gateway.rs | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 4cc450a..09fcc63 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -29,35 +29,30 @@ async fn test_gateway_authenticate() { #[tokio::test] async fn test_self_updating_structs() { let mut bundle = common::setup().await; - let channel_updater = bundle.user.gateway.observe(bundle.channel.clone()).await; - let received_channel = channel_updater.borrow().clone().read().unwrap().clone(); + let received_channel = bundle + .user + .gateway + .observe_and_into_inner(bundle.channel.clone()) + .await; assert_eq!(received_channel, bundle.channel.read().unwrap().clone()); - let updater = bundle.user.gateway.observe(bundle.channel.clone()).await; - assert_eq!( - updater - .borrow() - .clone() - .read() - .unwrap() - .clone() - .name - .unwrap(), - bundle.channel.read().unwrap().clone().name.unwrap() - ); - - let channel = bundle.channel.read().unwrap().clone(); let modify_schema = ChannelModifySchema { name: Some("selfupdating".to_string()), ..Default::default() }; - Channel::modify(&channel, modify_schema, &mut bundle.user) + received_channel + .modify(modify_schema, &mut bundle.user) .await .unwrap(); - assert_eq!( - updater.borrow().read().unwrap().clone().name.unwrap(), + bundle + .user + .gateway + .observe_and_into_inner(bundle.channel.clone()) + .await + .name + .unwrap(), "selfupdating".to_string() ); From e0340047fbee2577d7df6ae771df2e257d13ed3c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 01:11:48 +0200 Subject: [PATCH 093/237] Remove import --- tests/gateway.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 09fcc63..9cbcc49 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,7 @@ mod common; use chorus::gateway::*; -use chorus::types::{self, Channel, ChannelModifySchema}; +use chorus::types::{self, ChannelModifySchema}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; From 2af8388947de9a7dfae6d877ce95c5202869ffb6 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 14:05:37 +0200 Subject: [PATCH 094/237] Add GuildRoleCreate and -Update --- src/gateway.rs | 11 +++++++--- src/types/events/guild.rs | 46 +++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index a39cb0f..695e893 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -1,7 +1,8 @@ use crate::errors::GatewayError; use crate::gateway::events::Events; use crate::types::{ - self, Channel, ChannelUpdate, Composite, JsonField, Snowflake, UpdateMessage, WebSocketEvent, + self, Channel, ChannelUpdate, Composite, Guild, GuildRoleCreate, GuildRoleUpdate, JsonField, + RoleObject, Snowflake, UpdateMessage, WebSocketEvent, }; use async_trait::async_trait; use std::any::Any; @@ -231,6 +232,8 @@ impl GatewayHandle { } } + /// Recursively observes and updates all updateable fields on the struct T. Returns an object + /// with all of its observable fields being observed. pub async fn observe_and_get>( &self, object: Arc>, @@ -240,6 +243,8 @@ impl GatewayHandle { object } + /// Recursively observes and updates all updateable fields on the struct T. Returns an object `T` + /// with all of its observable fields being observed. pub async fn observe_and_into_inner>( &self, object: Arc>, @@ -592,8 +597,8 @@ impl Gateway { "GUILD_MEMBER_REMOVE" => guild.member_remove, "GUILD_MEMBER_UPDATE" => guild.member_update, "GUILD_MEMBERS_CHUNK" => guild.members_chunk, - "GUILD_ROLE_CREATE" => guild.role_create, - "GUILD_ROLE_UPDATE" => guild.role_update, + "GUILD_ROLE_CREATE" => guild.role_create GuildRoleCreate: Guild, + "GUILD_ROLE_UPDATE" => guild.role_update GuildRoleUpdate: RoleObject, "GUILD_ROLE_DELETE" => guild.role_delete, "GUILD_SCHEDULED_EVENT_CREATE" => guild.role_scheduled_event_create, "GUILD_SCHEDULED_EVENT_UPDATE" => guild.role_scheduled_event_update, diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 2cbdbd0..84ac5b8 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -1,13 +1,17 @@ +use std::sync::{Arc, RwLock}; + +use chorus_macros::JsonField; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::types::entities::{Guild, PublicUser, UnavailableGuild}; use crate::types::events::WebSocketEvent; use crate::types::{ - AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, RoleObject, Snowflake, Sticker, + AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, JsonField, RoleObject, Snowflake, + Sticker, }; -use super::PresenceUpdate; +use super::{PresenceUpdate, UpdateMessage}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// See ; @@ -164,24 +168,58 @@ pub struct GuildMembersChunk { impl WebSocketEvent for GuildMembersChunk {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct GuildRoleCreate { pub guild_id: Snowflake, pub role: RoleObject, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for GuildRoleCreate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +impl UpdateMessage for GuildRoleCreate { + fn id(&self) -> Snowflake { + self.guild_id + } + + fn update(&mut self, object_to_update: Arc>) { + let mut object_to_update = object_to_update.write().unwrap(); + if object_to_update.roles.is_some() { + object_to_update + .roles + .as_mut() + .unwrap() + .push(Arc::new(RwLock::new(self.role.clone()))); + } else { + object_to_update.roles = Some(Vec::from([Arc::new(RwLock::new(self.role.clone()))])); + } + } +} + +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct GuildRoleUpdate { pub guild_id: Snowflake, pub role: RoleObject, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for GuildRoleUpdate {} +impl UpdateMessage for GuildRoleUpdate { + fn id(&self) -> Snowflake { + self.role.id + } + + fn update(&mut self, object_to_update: Arc>) { + let mut write = object_to_update.write().unwrap(); + *write = self.role.clone(); + } +} + #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See pub struct GuildRoleDelete { From 9ce75482d12ddc48b17d6da72b31d7e39df66cf8 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 14:05:44 +0200 Subject: [PATCH 095/237] Make Role Clone --- src/types/schema/role.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/schema/role.rs b/src/types/schema/role.rs index 4ae300d..284f506 100644 --- a/src/types/schema/role.rs +++ b/src/types/schema/role.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone)] #[serde(rename_all = "snake_case")] /// Represents the schema which needs to be sent to create or modify a Role. /// See: [https://docs.spacebar.chat/routes/#cmp--schemas-rolemodifyschema](https://docs.spacebar.chat/routes/#cmp--schemas-rolemodifyschema) From 116c829f289ea72483c29115f0806c29c1cca30b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 14:05:51 +0200 Subject: [PATCH 096/237] Rename update to modify --- src/api/guilds/roles.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 91b7bd4..271cf90 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -120,13 +120,13 @@ impl types::RoleObject { .await } - /// Updates a role in a guild. + /// Modifies a role in a guild. /// /// Requires the [`MANAGE_ROLES`](crate::types::PermissionFlags::MANAGE_ROLES) permission. /// /// # Reference /// See - pub async fn update( + pub async fn modify( user: &mut UserMeta, guild_id: Snowflake, role_id: Snowflake, From e9f94267c61f9f1b50c288bf27549b61bcc6ae57 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 14:06:04 +0200 Subject: [PATCH 097/237] Add recursive-updating-structs test --- tests/gateway.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 9cbcc49..3876ef6 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,11 @@ mod common; +use std::sync::{Arc, RwLock}; + use chorus::gateway::*; -use chorus::types::{self, ChannelModifySchema}; +use chorus::types::{ + self, ChannelModifySchema, Composite, PermissionFlags, RoleCreateModifySchema, RoleObject, +}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -58,3 +62,51 @@ async fn test_self_updating_structs() { common::teardown(bundle).await } + +#[tokio::test] +async fn test_recursive_self_updating_structs() { + let mut bundle = common::setup().await; + + let guild = bundle + .user + .gateway + .observe_and_into_inner(bundle.guild.clone()) + .await; + assert!(guild.roles.is_none()); + let id = guild.id; + let permissions = PermissionFlags::CONNECT | PermissionFlags::MANAGE_EVENTS; + let permissions = Some(permissions.to_string()); + let mut role_create_schema = RoleCreateModifySchema { + name: Some("among us".to_string()), + permissions, + hoist: Some(true), + icon: None, + unicode_emoji: Some("".to_string()), + mentionable: Some(true), + position: None, + color: None, + }; + let role = RoleObject::create(&mut bundle.user, id, role_create_schema.clone()) + .await + .unwrap(); + let role_watch = bundle + .user + .gateway + .observer_channel(Arc::new(RwLock::new(role.clone()))) + .await; + let guild = bundle + .user + .gateway + .observe_and_into_inner(bundle.guild.clone()) + .await; + assert!(guild.roles.is_some()); + role_create_schema.name = Some("enbyenvy".to_string()); + RoleObject::modify(&mut bundle.user, id, role.id, role_create_schema) + .await + .unwrap(); + let newrole = role_watch.borrow().read().unwrap().clone(); + assert_eq!(newrole.name, "enbyenvy".to_string()); + let guild_role = role_watch.borrow().read().unwrap().clone(); + assert_eq!(guild_role.name, "enbyenvy".to_string()); + common::teardown(bundle).await; +} From fbf72b74d0634ac9f11eb797877e4f74b2734ab8 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 21:26:19 +0200 Subject: [PATCH 098/237] Remove tokio watch channels --- src/gateway.rs | 76 +++++++++++++++++++----------------------------- tests/gateway.rs | 51 ++------------------------------ 2 files changed, 33 insertions(+), 94 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 695e893..e1c4836 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -10,7 +10,6 @@ use std::collections::HashMap; use std::fmt::Debug; use std::sync::{Arc, RwLock}; use std::time::Duration; -use tokio::sync::watch; use tokio::time::sleep_until; use futures_util::stream::SplitSink; @@ -150,14 +149,12 @@ impl GatewayMessage { } } +pub type ObservableObject = dyn Send + Sync + Any; + /// Represents a handle to a Gateway connection. A Gateway connection will create observable /// [`GatewayEvents`](GatewayEvent), which you can subscribe to. Gateway events include all currently /// implemented types with the trait [`WebSocketEvent`] /// Using this handle you can also send Gateway Events directly. -/// -/// # Store -/// The value of `store`s [`HashMap`] is a [`tokio::sync::watch::channel`]. See the -/// [`Updateable`] trait for more information. #[derive(Debug)] pub struct GatewayHandle { pub url: String, @@ -173,7 +170,7 @@ pub struct GatewayHandle { pub handle: JoinHandle<()>, /// Tells gateway tasks to close kill_send: tokio::sync::broadcast::Sender<()>, - store: Arc>>>, + store: Arc>>>>, } /// An entity type which is supposed to be updateable via the Gateway. This is implemented for all such types chorus supports, implementing it for your own types is likely a mistake. @@ -202,55 +199,42 @@ impl GatewayHandle { .unwrap(); } - pub async fn observer_channel>( + pub async fn observe>( &self, object: Arc>, - ) -> watch::Receiver>> { + ) -> Arc> { let mut store = self.store.lock().await; let id = object.read().unwrap().id(); if let Some(channel) = store.get(&id) { - let (_, rx) = channel - .downcast_ref::<( - watch::Sender>>, - watch::Receiver>>, - )>() - .unwrap_or_else(|| { - panic!( - "Snowflake {} already exists in the store, but it is not of type T.", - object.read().unwrap().id() - ) - }); - rx.clone() + let object = channel.clone(); + let inner_object = object.read().unwrap(); + inner_object.downcast_ref::().unwrap_or_else(|| { + panic!( + "Snowflake {} already exists in the store, but it is not of type T.", + id + ) + }); + let ptr = Arc::into_raw(object.clone()); + unsafe { println!("{:?}", Arc::from_raw(ptr as *const RwLock).clone()) }; + unsafe { Arc::from_raw(ptr as *const RwLock).clone() } } else { let id = object.read().unwrap().id(); let object = object.read().unwrap().clone(); let object = object.clone().watch_whole(self).await; - let channel = watch::channel(Arc::new(RwLock::new(object))); - let receiver = channel.1.clone(); - store.insert(id, Box::new(channel)); - receiver + let wrapped = Arc::new(RwLock::new(object)); + store.insert(id, wrapped.clone()); + wrapped } } - /// Recursively observes and updates all updateable fields on the struct T. Returns an object - /// with all of its observable fields being observed. - pub async fn observe_and_get>( - &self, - object: Arc>, - ) -> Arc> { - let channel = self.observer_channel(object.clone()).await; - let object = channel.borrow().clone(); - object - } - /// Recursively observes and updates all updateable fields on the struct T. Returns an object `T` /// with all of its observable fields being observed. - pub async fn observe_and_into_inner>( + pub async fn observe_and_into_inner>( &self, object: Arc>, ) -> T { - let channel = self.observer_channel(object.clone()).await; - let object = channel.borrow().clone().read().unwrap().clone(); + let channel = self.observe(object.clone()).await; + let object = channel.read().unwrap().clone(); object } @@ -330,8 +314,6 @@ impl GatewayHandle { } } -/// The value of `store`s [`HashMap`] is a [`tokio::sync::watch::channel`]. See the -/// [`Updateable`] trait for more information. pub struct Gateway { events: Arc>, heartbeat_handler: HeartbeatHandler, @@ -345,7 +327,7 @@ pub struct Gateway { >, websocket_receive: SplitStream>>, kill_send: tokio::sync::broadcast::Sender<()>, - store: Arc>>>, + store: Arc>>>>, } impl Gateway { @@ -518,12 +500,14 @@ impl Gateway { $( let mut message: $message_type = message; if let Some(to_update) = self.store.lock().await.get(&message.id()) { - if let Some((tx, _)) = to_update.downcast_ref::<(watch::Sender>>, watch::Receiver>>)>() { - // `object` is the current value of the `watch::channel`. It's being passed into `message.update()` to be modified - // within the closure function. Then, this closure is passed to the `tx.send_modify()` method which applies the - // modification to the current value of the watch channel. + let object = to_update.clone(); + let inner_object = object.read().unwrap(); + if let Some(_) = inner_object.downcast_ref::<$update_type>() { + let ptr = Arc::into_raw(object.clone()); + let downcasted = unsafe { Arc::from_raw(ptr as *const RwLock<$update_type>).clone() }; + drop(inner_object); message.set_json(json.to_string()); - tx.send_modify(|object| message.update(object.clone())); + message.update(downcasted.clone()); } else { warn!("Received {} for {}, but it has been observed to be a different type!", $name, message.id()) } diff --git a/tests/gateway.rs b/tests/gateway.rs index 3876ef6..7c15bf6 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,11 +1,7 @@ mod common; -use std::sync::{Arc, RwLock}; - use chorus::gateway::*; -use chorus::types::{ - self, ChannelModifySchema, Composite, PermissionFlags, RoleCreateModifySchema, RoleObject, -}; +use chorus::types::{self, ChannelModifySchema}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -65,48 +61,7 @@ async fn test_self_updating_structs() { #[tokio::test] async fn test_recursive_self_updating_structs() { - let mut bundle = common::setup().await; - - let guild = bundle - .user - .gateway - .observe_and_into_inner(bundle.guild.clone()) - .await; - assert!(guild.roles.is_none()); - let id = guild.id; - let permissions = PermissionFlags::CONNECT | PermissionFlags::MANAGE_EVENTS; - let permissions = Some(permissions.to_string()); - let mut role_create_schema = RoleCreateModifySchema { - name: Some("among us".to_string()), - permissions, - hoist: Some(true), - icon: None, - unicode_emoji: Some("".to_string()), - mentionable: Some(true), - position: None, - color: None, - }; - let role = RoleObject::create(&mut bundle.user, id, role_create_schema.clone()) - .await - .unwrap(); - let role_watch = bundle - .user - .gateway - .observer_channel(Arc::new(RwLock::new(role.clone()))) - .await; - let guild = bundle - .user - .gateway - .observe_and_into_inner(bundle.guild.clone()) - .await; - assert!(guild.roles.is_some()); - role_create_schema.name = Some("enbyenvy".to_string()); - RoleObject::modify(&mut bundle.user, id, role.id, role_create_schema) - .await - .unwrap(); - let newrole = role_watch.borrow().read().unwrap().clone(); - assert_eq!(newrole.name, "enbyenvy".to_string()); - let guild_role = role_watch.borrow().read().unwrap().clone(); - assert_eq!(guild_role.name, "enbyenvy".to_string()); + // Setup + let bundle = common::setup().await; common::teardown(bundle).await; } From 887ba4a1b10cf0341e0a6bace1f15ea5456e9f04 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 21:26:27 +0200 Subject: [PATCH 099/237] Make trait Debug --- chorus-macros/src/lib.rs | 2 +- src/types/entities/channel.rs | 1 + src/types/entities/emoji.rs | 1 + src/types/entities/guild.rs | 1 + src/types/entities/mod.rs | 17 +++++++++++------ src/types/entities/role.rs | 1 + src/types/entities/user.rs | 1 + src/types/entities/voice_state.rs | 1 + src/types/entities/webhook.rs | 1 + src/types/events/channel.rs | 3 +++ 10 files changed, 22 insertions(+), 7 deletions(-) diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index baac40b..f825568 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -104,7 +104,7 @@ pub fn composite_derive(input: TokenStream) -> TokenStream { let ident = &input.ident; let expanded = quote! { #[async_trait::async_trait(?Send)] - impl Composite for #ident { + impl Composite for #ident { async fn watch_whole(self, gateway: &GatewayHandle) -> Self { Self { #(#field_exprs,)* diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index ad776d8..3866e01 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -5,6 +5,7 @@ use chrono::Utc; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_string_from_number; use serde_repr::{Deserialize_repr, Serialize_repr}; +use std::fmt::Debug; use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 308c41b..68700e6 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 7f73403..3f59055 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::sync::{Arc, RwLock}; use chorus_macros::{observe_option_vec, observe_vec, Composite, Updateable}; diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 7f8cc56..9267374 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -24,6 +24,7 @@ pub use webhook::*; use crate::gateway::{GatewayHandle, Updateable}; use async_trait::async_trait; +use std::fmt::Debug; use std::sync::{Arc, RwLock}; mod application; @@ -51,7 +52,7 @@ mod voice_state; mod webhook; #[async_trait(?Send)] -pub trait Composite { +pub trait Composite { async fn watch_whole(self, gateway: &GatewayHandle) -> Self; async fn option_observe_fn( @@ -59,11 +60,12 @@ pub trait Composite { gateway: &GatewayHandle, ) -> Option>> where - T: Composite, + T: Composite + Debug, { + println!("Processed option value."); if let Some(value) = value { let value = value.clone(); - Some(gateway.observe_and_get(value).await) + Some(gateway.observe(value).await) } else { None } @@ -76,10 +78,11 @@ pub trait Composite { where T: Composite, { + println!("Processed option vec value."); if let Some(value) = value { let mut vec = Vec::new(); for component in value.into_iter() { - vec.push(gateway.observe_and_get(component).await); + vec.push(gateway.observe(component).await); } Some(vec) } else { @@ -91,7 +94,8 @@ pub trait Composite { where T: Composite, { - gateway.observe_and_get(value).await + println!("Processed value."); + gateway.observe(value).await } async fn vec_observe_fn( @@ -101,9 +105,10 @@ pub trait Composite { where T: Composite, { + println!("Processed vec value."); let mut vec = Vec::new(); for component in value.into_iter() { - vec.push(gateway.observe_and_get(component).await); + vec.push(gateway.observe(component).await); } vec } diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 9fac835..22dceff 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -2,6 +2,7 @@ use bitflags::bitflags; use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::{deserialize_option_number_from_string, deserialize_string_from_number}; +use std::fmt::Debug; use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{utils::Snowflake, Composite}; diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 56329b2..aadfd35 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -2,6 +2,7 @@ use chorus_macros::{Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; +use std::fmt::Debug; use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{utils::Snowflake, Composite}; diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index e74aa7d..c879c8e 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -3,6 +3,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use std::fmt::Debug; use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index dd88ca1..7771dbf 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::sync::{Arc, RwLock}; use chorus_macros::{Composite, Updateable}; diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 017c50e..5b693db 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -42,6 +42,9 @@ impl UpdateMessage for ChannelUpdate { fn update(&mut self, object_to_update: Arc>) { let mut write = object_to_update.write().unwrap(); *write = self.channel.clone(); + drop(write); + println!("{:?}", self.channel.name); + assert_eq!(self.channel.name, object_to_update.read().unwrap().name); } fn id(&self) -> Snowflake { self.channel.id From 29b9050e6d56ba5762cd52123144f76bdd8897b9 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 22:04:07 +0200 Subject: [PATCH 100/237] Make store pub(crate), other adjustments --- src/gateway.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index e1c4836..77736be 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -170,7 +170,7 @@ pub struct GatewayHandle { pub handle: JoinHandle<()>, /// Tells gateway tasks to close kill_send: tokio::sync::broadcast::Sender<()>, - store: Arc>>>>, + pub(crate) store: Arc>>>>, } /// An entity type which is supposed to be updateable via the Gateway. This is implemented for all such types chorus supports, implementing it for your own types is likely a mistake. @@ -215,7 +215,7 @@ impl GatewayHandle { ) }); let ptr = Arc::into_raw(object.clone()); - unsafe { println!("{:?}", Arc::from_raw(ptr as *const RwLock).clone()) }; + //unsafe { println!("{:?}", Arc::from_raw(ptr as *const RwLock).clone()) }; unsafe { Arc::from_raw(ptr as *const RwLock).clone() } } else { let id = object.read().unwrap().id(); @@ -499,13 +499,16 @@ impl Gateway { Ok(message) => { $( let mut message: $message_type = message; - if let Some(to_update) = self.store.lock().await.get(&message.id()) { + let mut store = self.store.lock().await; + if let Some(to_update) = store.get(&message.id()) { let object = to_update.clone(); let inner_object = object.read().unwrap(); if let Some(_) = inner_object.downcast_ref::<$update_type>() { let ptr = Arc::into_raw(object.clone()); let downcasted = unsafe { Arc::from_raw(ptr as *const RwLock<$update_type>).clone() }; drop(inner_object); + store.insert(message.id(), downcasted.clone()); + println!("yippie"); message.set_json(json.to_string()); message.update(downcasted.clone()); } else { From 7c8ad3ffcf2ea0756e6f3edd3b67a6c883c5d95b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 22:04:24 +0200 Subject: [PATCH 101/237] Rewrite recursive update test (still fails sob) --- tests/gateway.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 7c15bf6..86cf947 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -1,7 +1,9 @@ mod common; +use std::sync::{Arc, RwLock}; + use chorus::gateway::*; -use chorus::types::{self, ChannelModifySchema}; +use chorus::types::{self, ChannelModifySchema, RoleCreateModifySchema, RoleObject}; #[tokio::test] /// Tests establishing a connection (hello and heartbeats) on the local gateway; @@ -62,6 +64,48 @@ async fn test_self_updating_structs() { #[tokio::test] async fn test_recursive_self_updating_structs() { // Setup - let bundle = common::setup().await; + let mut bundle = common::setup().await; + let guild = bundle.guild.clone(); + // Observe Guild, make sure it has no channels + let guild = bundle.user.gateway.observe(guild.clone()).await; + let inner_guild = guild.read().unwrap().clone(); + assert!(inner_guild.roles.is_none()); + // Create Role + let permissions = types::PermissionFlags::CONNECT | types::PermissionFlags::MANAGE_EVENTS; + let permissions = Some(permissions.to_string()); + let mut role_create_schema: types::RoleCreateModifySchema = RoleCreateModifySchema { + name: Some("cool person".to_string()), + permissions, + hoist: Some(true), + icon: None, + unicode_emoji: Some("".to_string()), + mentionable: Some(true), + position: None, + color: None, + }; + let guild_id = inner_guild.id; + let role = RoleObject::create(&mut bundle.user, guild_id, role_create_schema.clone()) + .await + .unwrap(); + // Watch role; + bundle + .user + .gateway + .observe(Arc::new(RwLock::new(role.clone()))) + .await; + // Update Guild and check for Guild + let guild = bundle.user.gateway.observe(guild.clone()).await; + let inner_guild = guild.read().unwrap().clone(); + assert!(inner_guild.roles.is_some()); + // Update the Role + role_create_schema.name = Some("yippieee".to_string()); + RoleObject::modify(&mut bundle.user, guild_id, role.id, role_create_schema) + .await + .unwrap(); + // Check if the change propagated + let guild_roles = guild.read().unwrap().clone().roles; + let guild_role = guild_roles.unwrap(); + let guild_role_inner = guild_role.get(0).unwrap().read().unwrap().clone(); + assert_eq!(guild_role_inner.name, "yippieee".to_string()); common::teardown(bundle).await; } From a1df997c9f0b2dc1a46c42b5106cc4da0da4855f Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 22:04:36 +0200 Subject: [PATCH 102/237] I think i found out why shit no work --- src/types/events/guild.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 84ac5b8..28e917a 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -215,7 +215,9 @@ impl UpdateMessage for GuildRoleUpdate { } fn update(&mut self, object_to_update: Arc>) { + println!("Processing Role Update. Name: {}", self.role.name); let mut write = object_to_update.write().unwrap(); + // FIXME: The result of this update never gets saved in the store of GatewayHandle... This is why shit no work *write = self.role.clone(); } } From 4210bd6d73bac24f76cdb2749e58f0d2bc1630fa Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 16 Aug 2023 22:04:43 +0200 Subject: [PATCH 103/237] Remove debug prints --- src/types/events/channel.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 5b693db..017c50e 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -42,9 +42,6 @@ impl UpdateMessage for ChannelUpdate { fn update(&mut self, object_to_update: Arc>) { let mut write = object_to_update.write().unwrap(); *write = self.channel.clone(); - drop(write); - println!("{:?}", self.channel.name); - assert_eq!(self.channel.name, object_to_update.read().unwrap().name); } fn id(&self) -> Snowflake { self.channel.id From adf3d4ef3195eba10b188715d270740e3fb7cc7e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 17 Aug 2023 18:23:57 +0200 Subject: [PATCH 104/237] Update test a little --- tests/gateway.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/gateway.rs b/tests/gateway.rs index 86cf947..be1cb10 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -94,7 +94,6 @@ async fn test_recursive_self_updating_structs() { .observe(Arc::new(RwLock::new(role.clone()))) .await; // Update Guild and check for Guild - let guild = bundle.user.gateway.observe(guild.clone()).await; let inner_guild = guild.read().unwrap().clone(); assert!(inner_guild.roles.is_some()); // Update the Role @@ -102,8 +101,16 @@ async fn test_recursive_self_updating_structs() { RoleObject::modify(&mut bundle.user, guild_id, role.id, role_create_schema) .await .unwrap(); + let role_inner = bundle + .user + .gateway + .observe_and_into_inner(Arc::new(RwLock::new(role.clone()))) + .await; + assert_eq!(role_inner.name, "yippieee"); // Check if the change propagated - let guild_roles = guild.read().unwrap().clone().roles; + let guild = bundle.user.gateway.observe(bundle.guild.clone()).await; + let inner_guild = guild.read().unwrap().clone(); + let guild_roles = inner_guild.roles; let guild_role = guild_roles.unwrap(); let guild_role_inner = guild_role.get(0).unwrap().read().unwrap().clone(); assert_eq!(guild_role_inner.name, "yippieee".to_string()); From 711580f270221dcbf67658acda310c0a799f79c9 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 17 Aug 2023 18:26:06 +0200 Subject: [PATCH 105/237] Call watch_whole either way --- src/gateway.rs | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 77736be..9bd4e12 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -207,16 +207,28 @@ impl GatewayHandle { let id = object.read().unwrap().id(); if let Some(channel) = store.get(&id) { let object = channel.clone(); - let inner_object = object.read().unwrap(); - inner_object.downcast_ref::().unwrap_or_else(|| { - panic!( - "Snowflake {} already exists in the store, but it is not of type T.", - id - ) - }); + drop(store); + object + .read() + .unwrap() + .downcast_ref::() + .unwrap_or_else(|| { + panic!( + "Snowflake {} already exists in the store, but it is not of type T.", + id + ) + }); let ptr = Arc::into_raw(object.clone()); - //unsafe { println!("{:?}", Arc::from_raw(ptr as *const RwLock).clone()) }; - unsafe { Arc::from_raw(ptr as *const RwLock).clone() } + // SAFETY: + // - We have just checked that the typeid of the `dyn Any ...` matches that of `T`. + // - This operation doesn't read or write any shared data, and thus cannot cause a data race + // - The reference count is not being modified + let downcasted = unsafe { Arc::from_raw(ptr as *const RwLock).clone() }; + let object = downcasted.read().unwrap().clone(); + + let watched_object = object.watch_whole(self).await; + *downcasted.write().unwrap() = watched_object; + downcasted } else { let id = object.read().unwrap().id(); let object = object.read().unwrap().clone(); @@ -499,16 +511,18 @@ impl Gateway { Ok(message) => { $( let mut message: $message_type = message; - let mut store = self.store.lock().await; + let store = self.store.lock().await; if let Some(to_update) = store.get(&message.id()) { let object = to_update.clone(); let inner_object = object.read().unwrap(); if let Some(_) = inner_object.downcast_ref::<$update_type>() { let ptr = Arc::into_raw(object.clone()); + // SAFETY: + // - We have just checked that the typeid of the `dyn Any ...` matches that of `T`. + // - This operation doesn't read or write any shared data, and thus cannot cause a data race + // - The reference count is not being modified let downcasted = unsafe { Arc::from_raw(ptr as *const RwLock<$update_type>).clone() }; drop(inner_object); - store.insert(message.id(), downcasted.clone()); - println!("yippie"); message.set_json(json.to_string()); message.update(downcasted.clone()); } else { From d69a4590255e64f9dafe54ae877016656b0357e6 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 17 Aug 2023 18:26:14 +0200 Subject: [PATCH 106/237] Remove prints --- src/types/entities/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 9267374..abdf976 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -62,7 +62,6 @@ pub trait Composite { where T: Composite + Debug, { - println!("Processed option value."); if let Some(value) = value { let value = value.clone(); Some(gateway.observe(value).await) @@ -78,7 +77,6 @@ pub trait Composite { where T: Composite, { - println!("Processed option vec value."); if let Some(value) = value { let mut vec = Vec::new(); for component in value.into_iter() { @@ -94,7 +92,6 @@ pub trait Composite { where T: Composite, { - println!("Processed value."); gateway.observe(value).await } @@ -105,7 +102,6 @@ pub trait Composite { where T: Composite, { - println!("Processed vec value."); let mut vec = Vec::new(); for component in value.into_iter() { vec.push(gateway.observe(component).await); From 4424e3f07a4beae491974cfa91a7fab6f66488e1 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 17 Aug 2023 18:26:34 +0200 Subject: [PATCH 107/237] Remove comment --- src/types/events/guild.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 28e917a..5fac86b 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -217,8 +217,8 @@ impl UpdateMessage for GuildRoleUpdate { fn update(&mut self, object_to_update: Arc>) { println!("Processing Role Update. Name: {}", self.role.name); let mut write = object_to_update.write().unwrap(); - // FIXME: The result of this update never gets saved in the store of GatewayHandle... This is why shit no work *write = self.role.clone(); + println!("Updated role: Name: {}", write.name); } } From 0396e318d3336e8cef232e824b8ab061f67d569e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 17 Aug 2023 22:26:07 +0200 Subject: [PATCH 108/237] Change bearer_auth to header("Authorization" --- src/api/channels/channels.rs | 12 ++++++------ src/api/channels/messages.rs | 4 ++-- src/api/channels/permissions.rs | 9 +++++++-- src/api/channels/reactions.rs | 20 ++++++++++++++------ src/api/guilds/guilds.rs | 10 +++++----- src/api/guilds/member.rs | 8 +++++--- src/api/guilds/roles.rs | 13 ++++++++----- src/api/invites/mod.rs | 6 +++--- src/api/users/channels.rs | 2 +- src/api/users/guilds.rs | 2 +- src/api/users/relationships.rs | 19 ++++++++++++------- src/api/users/users.rs | 10 ++++++---- 12 files changed, 70 insertions(+), 45 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 1e8f93c..276636f 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -20,7 +20,7 @@ impl Channel { let chorus_request = ChorusRequest { request: Client::new() .get(format!("{}/channels/{}", url, channel_id)) - .bearer_auth(user.token()), + .header("Authorization", user.token()), limit_type: LimitType::Channel(channel_id), }; chorus_request.deserialize_response::(user).await @@ -41,7 +41,7 @@ impl Channel { user.belongs_to.borrow().urls.api, self.id )) - .bearer_auth(user.token()), + .header("Authorization", user.token()), limit_type: LimitType::Channel(self.id), }; chorus_request.handle_request_as_result(user).await @@ -74,7 +74,7 @@ impl Channel { user.belongs_to.borrow().urls.api, channel_id )) - .bearer_auth(user.token()) + .header("Authorization", user.token()) .body(to_string(&modify_data).unwrap()), limit_type: LimitType::Channel(channel_id), }; @@ -102,7 +102,7 @@ impl Channel { user.belongs_to.borrow().urls.api, channel_id )) - .bearer_auth(user.token()) + .header("Authorization", user.token()) .query(&range), limit_type: Default::default(), }; @@ -129,7 +129,7 @@ impl Channel { self.id, recipient_id )) - .bearer_auth(user.token()); + .header("Authorization", user.token()); if let Some(schema) = add_channel_recipient_schema { request = request.body(to_string(&schema).unwrap()); } @@ -157,7 +157,7 @@ impl Channel { self.id, recipient_id )) - .bearer_auth(user.token()); + .header("Authorization", user.token()); ChorusRequest { request, limit_type: LimitType::Channel(self.id), diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index b93ce2e..25995f9 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -26,7 +26,7 @@ impl Message { let chorus_request = ChorusRequest { request: Client::new() .post(format!("{}/channels/{}/messages", url_api, channel_id)) - .bearer_auth(user.token()) + .header("Authorization", user.token()) .body(to_string(&message).unwrap()), limit_type: LimitType::Channel(channel_id), }; @@ -62,7 +62,7 @@ impl Message { let chorus_request = ChorusRequest { request: Client::new() .post(format!("{}/channels/{}/messages", url_api, channel_id)) - .bearer_auth(user.token()) + .header("Authorization", user.token()) .multipart(form), limit_type: LimitType::Channel(channel_id), }; diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 7c83d85..b445876 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -40,7 +40,10 @@ impl types::Channel { } }; let chorus_request = ChorusRequest { - request: Client::new().put(url).bearer_auth(user.token()).body(body), + request: Client::new() + .put(url) + .header("Authorization", user.token()) + .body(body), limit_type: LimitType::Channel(channel_id), }; chorus_request.handle_request_as_result(user).await @@ -66,7 +69,9 @@ impl types::Channel { overwrite_id ); let chorus_request = ChorusRequest { - request: Client::new().delete(url).bearer_auth(user.token()), + request: Client::new() + .delete(url) + .header("Authorization", user.token()), limit_type: LimitType::Channel(channel_id), }; chorus_request.handle_request_as_result(user).await diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index 05fcea0..f9b7541 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -29,7 +29,9 @@ impl ReactionMeta { self.message_id ); let chorus_request = ChorusRequest { - request: Client::new().delete(url).bearer_auth(user.token()), + request: Client::new() + .delete(url) + .header("Authorization", user.token()), limit_type: LimitType::Channel(self.channel_id), }; chorus_request.handle_request_as_result(user).await @@ -51,7 +53,7 @@ impl ReactionMeta { emoji ); let chorus_request = ChorusRequest { - request: Client::new().get(url).bearer_auth(user.token()), + request: Client::new().get(url).header("Authorization", user.token()), limit_type: LimitType::Channel(self.channel_id), }; chorus_request @@ -77,7 +79,9 @@ impl ReactionMeta { emoji ); let chorus_request = ChorusRequest { - request: Client::new().delete(url).bearer_auth(user.token()), + request: Client::new() + .delete(url) + .header("Authorization", user.token()), limit_type: LimitType::Channel(self.channel_id), }; chorus_request.handle_request_as_result(user).await @@ -104,7 +108,7 @@ impl ReactionMeta { emoji ); let chorus_request = ChorusRequest { - request: Client::new().put(url).bearer_auth(user.token()), + request: Client::new().put(url).header("Authorization", user.token()), limit_type: LimitType::Channel(self.channel_id), }; chorus_request.handle_request_as_result(user).await @@ -126,7 +130,9 @@ impl ReactionMeta { emoji ); let chorus_request = ChorusRequest { - request: Client::new().delete(url).bearer_auth(user.token()), + request: Client::new() + .delete(url) + .header("Authorization", user.token()), limit_type: LimitType::Channel(self.channel_id), }; chorus_request.handle_request_as_result(user).await @@ -156,7 +162,9 @@ impl ReactionMeta { user_id ); let chorus_request = ChorusRequest { - request: Client::new().delete(url).bearer_auth(user.token()), + request: Client::new() + .delete(url) + .header("Authorization", user.token()), limit_type: LimitType::Channel(self.channel_id), }; chorus_request.handle_request_as_result(user).await diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 0c8b9cf..9031563 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -23,7 +23,7 @@ impl Guild { let chorus_request = ChorusRequest { request: Client::new() .post(url.clone()) - .bearer_auth(user.token.clone()) + .header("Authorization", user.token.clone()) .body(to_string(&guild_create_schema).unwrap()), limit_type: LimitType::Global, }; @@ -58,7 +58,7 @@ impl Guild { let chorus_request = ChorusRequest { request: Client::new() .post(url.clone()) - .bearer_auth(user.token.clone()), + .header("Authorization", user.token.clone()), limit_type: LimitType::Global, }; chorus_request.handle_request_as_result(user).await @@ -95,7 +95,7 @@ impl Guild { user.belongs_to.borrow().urls.api, self.id )) - .bearer_auth(user.token()), + .header("Authorization", user.token()), limit_type: LimitType::Channel(self.id), }; let result = chorus_request.send_request(user).await?; @@ -129,7 +129,7 @@ impl Guild { user.belongs_to.borrow().urls.api, guild_id )) - .bearer_auth(user.token()), + .header("Authorization", user.token()), limit_type: LimitType::Guild(guild_id), }; let response = chorus_request.deserialize_response::(user).await?; @@ -156,7 +156,7 @@ impl Channel { user.belongs_to.borrow().urls.api, guild_id )) - .bearer_auth(user.token()) + .header("Authorization", user.token()) .body(to_string(&schema).unwrap()), limit_type: LimitType::Guild(guild_id), }; diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index 28fa68f..dcced7e 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -25,7 +25,7 @@ impl types::GuildMember { member_id ); let chorus_request = ChorusRequest { - request: Client::new().get(url).bearer_auth(user.token()), + request: Client::new().get(url).header("Authorization", user.token()), limit_type: LimitType::Guild(guild_id), }; chorus_request @@ -53,7 +53,7 @@ impl types::GuildMember { role_id ); let chorus_request = ChorusRequest { - request: Client::new().put(url).bearer_auth(user.token()), + request: Client::new().put(url).header("Authorization", user.token()), limit_type: LimitType::Guild(guild_id), }; chorus_request.handle_request_as_result(user).await @@ -79,7 +79,9 @@ impl types::GuildMember { role_id ); let chorus_request = ChorusRequest { - request: Client::new().delete(url).bearer_auth(user.token()), + request: Client::new() + .delete(url) + .header("Authorization", user.token()), limit_type: LimitType::Guild(guild_id), }; chorus_request.handle_request_as_result(user).await diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 271cf90..c0893a8 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -24,7 +24,7 @@ impl types::RoleObject { guild_id ); let chorus_request = ChorusRequest { - request: Client::new().get(url).bearer_auth(user.token()), + request: Client::new().get(url).header("Authorization", user.token()), limit_type: LimitType::Guild(guild_id), }; let roles = chorus_request @@ -50,7 +50,7 @@ impl types::RoleObject { role_id ); let chorus_request = ChorusRequest { - request: Client::new().get(url).bearer_auth(user.token()), + request: Client::new().get(url).header("Authorization", user.token()), limit_type: LimitType::Guild(guild_id), }; chorus_request @@ -80,7 +80,10 @@ impl types::RoleObject { } })?; let chorus_request = ChorusRequest { - request: Client::new().post(url).bearer_auth(user.token()).body(body), + request: Client::new() + .post(url) + .header("Authorization", user.token()) + .body(body), limit_type: LimitType::Guild(guild_id), }; chorus_request @@ -111,7 +114,7 @@ impl types::RoleObject { let chorus_request = ChorusRequest { request: Client::new() .patch(url) - .bearer_auth(user.token()) + .header("Authorization", user.token()) .body(body), limit_type: LimitType::Guild(guild_id), }; @@ -146,7 +149,7 @@ impl types::RoleObject { let chorus_request = ChorusRequest { request: Client::new() .patch(url) - .bearer_auth(user.token()) + .header("Authorization", user.token()) .body(body), limit_type: LimitType::Guild(guild_id), }; diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index ac9c120..c32d30a 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -25,7 +25,7 @@ impl UserMeta { self.belongs_to.borrow().urls.api, invite_code )) - .bearer_auth(self.token()), + .header("Authorization", self.token()), limit_type: super::LimitType::Global, }; if session_id.is_some() { @@ -50,7 +50,7 @@ impl UserMeta { self.belongs_to.borrow().urls.api )) .body(to_string(&code).unwrap()) - .bearer_auth(self.token()), + .header("Authorization", self.token()), limit_type: super::LimitType::Global, } .deserialize_response::(self) @@ -76,7 +76,7 @@ impl UserMeta { self.belongs_to.borrow().urls.api, channel_id )) - .bearer_auth(self.token()) + .header("Authorization", self.token()) .body(to_string(&create_channel_invite_schema).unwrap()), limit_type: super::LimitType::Channel(channel_id), } diff --git a/src/api/users/channels.rs b/src/api/users/channels.rs index faa58ad..74f7484 100644 --- a/src/api/users/channels.rs +++ b/src/api/users/channels.rs @@ -25,7 +25,7 @@ impl UserMeta { ChorusRequest { request: Client::new() .post(url) - .bearer_auth(self.token()) + .header("Authorization", self.token()) .body(to_string(&create_private_channel_schema).unwrap()), limit_type: LimitType::Global, } diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index 3967e8e..f1e586d 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -22,7 +22,7 @@ impl UserMeta { self.belongs_to.borrow().urls.api, guild_id )) - .bearer_auth(self.token()) + .header("Authorization", self.token()) .body(to_string(&lurking).unwrap()), limit_type: crate::api::LimitType::Guild(*guild_id), } diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index 41270e1..2cf0c6c 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -26,7 +26,7 @@ impl UserMeta { user_id ); let chorus_request = ChorusRequest { - request: Client::new().get(url).bearer_auth(self.token()), + request: Client::new().get(url).header("Authorization", self.token()), limit_type: LimitType::Global, }; chorus_request @@ -44,7 +44,7 @@ impl UserMeta { self.belongs_to.borrow().urls.api ); let chorus_request = ChorusRequest { - request: Client::new().get(url).bearer_auth(self.token()), + request: Client::new().get(url).header("Authorization", self.token()), limit_type: LimitType::Global, }; chorus_request @@ -66,7 +66,10 @@ impl UserMeta { ); let body = to_string(&schema).unwrap(); let chorus_request = ChorusRequest { - request: Client::new().post(url).bearer_auth(self.token()).body(body), + request: Client::new() + .post(url) + .header("Authorization", self.token()) + .body(body), limit_type: LimitType::Global, }; chorus_request.handle_request_as_result(self).await @@ -86,7 +89,7 @@ impl UserMeta { let chorus_request = ChorusRequest { request: Client::new() .delete(format!("{}/users/@me/relationships/{}", api_url, user_id)) - .bearer_auth(self.token()), + .header("Authorization", self.token()), limit_type: LimitType::Global, }; chorus_request.handle_request_as_result(self).await @@ -100,7 +103,7 @@ impl UserMeta { let chorus_request = ChorusRequest { request: Client::new() .put(format!("{}/users/@me/relationships/{}", api_url, user_id)) - .bearer_auth(self.token()) + .header("Authorization", self.token()) .body(to_string(&body).unwrap()), limit_type: LimitType::Global, }; @@ -115,7 +118,7 @@ impl UserMeta { let chorus_request = ChorusRequest { request: Client::new() .put(format!("{}/users/@me/relationships/{}", api_url, user_id)) - .bearer_auth(self.token()) + .header("Authorization", self.token()) .body(to_string(&body).unwrap()), limit_type: LimitType::Global, }; @@ -136,7 +139,9 @@ impl UserMeta { user_id ); let chorus_request = ChorusRequest { - request: Client::new().delete(url).bearer_auth(self.token()), + request: Client::new() + .delete(url) + .header("Authorization", self.token()), limit_type: LimitType::Global, }; chorus_request.handle_request_as_result(self).await diff --git a/src/api/users/users.rs b/src/api/users/users.rs index ff0638d..1ba4e84 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -50,7 +50,7 @@ impl UserMeta { let request = Client::new() .patch(format!("{}/users/@me", self.belongs_to.borrow().urls.api)) .body(to_string(&modify_schema).unwrap()) - .bearer_auth(self.token()); + .header("Authorization", self.token()); let chorus_request = ChorusRequest { request, limit_type: LimitType::default(), @@ -68,7 +68,7 @@ impl UserMeta { "{}/users/@me/delete", self.belongs_to.borrow().urls.api )) - .bearer_auth(self.token()); + .header("Authorization", self.token()); let chorus_request = ChorusRequest { request, limit_type: LimitType::default(), @@ -90,7 +90,9 @@ impl User { } else { format!("{}/users/{}", url_api, id.unwrap()) }; - let request = reqwest::Client::new().get(url).bearer_auth(user.token()); + let request = reqwest::Client::new() + .get(url) + .header("Authorization", user.token()); let chorus_request = ChorusRequest { request, limit_type: LimitType::Global, @@ -115,7 +117,7 @@ impl User { ) -> ChorusResult { let request: reqwest::RequestBuilder = Client::new() .get(format!("{}/users/@me/settings", url_api)) - .bearer_auth(token); + .header("Authorization", token); let mut user = UserMeta::shell(Rc::new(RefCell::new(instance.clone())), token.clone()).await; let chorus_request = ChorusRequest { From c2c1ad93b6ffef068ab4ed8c6ff5b623414af46d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 17 Aug 2023 22:45:42 +0200 Subject: [PATCH 109/237] Change type of Channel::last_pin_timestamp --- src/types/entities/channel.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 3866e01..a64b44c 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -1,7 +1,7 @@ use std::sync::{Arc, RwLock}; use chorus_macros::{observe_option_vec, Composite, Updateable}; -use chrono::Utc; +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_string_from_number; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -47,7 +47,7 @@ pub struct Channel { pub icon: Option, pub id: Snowflake, pub last_message_id: Option, - pub last_pin_timestamp: Option, + pub last_pin_timestamp: Option>, pub managed: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub member: Option, From 905b7af6189722fff029e425da513d33a4329731 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Fri, 18 Aug 2023 11:41:06 +0200 Subject: [PATCH 110/237] Add content type specification --- src/api/auth/login.rs | 3 ++- src/api/auth/register.rs | 3 ++- src/api/channels/channels.rs | 4 +++- src/api/channels/messages.rs | 3 ++- src/api/channels/permissions.rs | 1 + src/api/channels/reactions.rs | 5 ++++- src/api/guilds/guilds.rs | 5 ++++- src/api/guilds/member.rs | 5 ++++- src/api/guilds/roles.rs | 3 +++ src/api/invites/mod.rs | 5 ++++- src/api/users/channels.rs | 1 + src/api/users/guilds.rs | 1 + src/api/users/relationships.rs | 1 + src/api/users/users.rs | 6 ++++-- 14 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 3b3ffc6..34a873b 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -22,7 +22,8 @@ impl Instance { let chorus_request = ChorusRequest { request: Client::new() .post(endpoint_url) - .body(to_string(login_schema).unwrap()), + .body(to_string(login_schema).unwrap()) + .header("Content-Type", "application/json"), limit_type: LimitType::AuthLogin, }; // We do not have a user yet, and the UserRateLimits will not be affected by a login diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 7beaa76..b4350d2 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -27,7 +27,8 @@ impl Instance { let chorus_request = ChorusRequest { request: Client::new() .post(endpoint_url) - .body(to_string(register_schema).unwrap()), + .body(to_string(register_schema).unwrap()) + .header("Content-Type", "application/json"), limit_type: LimitType::AuthRegister, }; // We do not have a user yet, and the UserRateLimits will not be affected by a login diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 276636f..14c295a 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -75,6 +75,7 @@ impl Channel { channel_id )) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(to_string(&modify_data).unwrap()), limit_type: LimitType::Channel(channel_id), }; @@ -129,7 +130,8 @@ impl Channel { self.id, recipient_id )) - .header("Authorization", user.token()); + .header("Authorization", user.token()) + .header("Content-Type", "application/json"); if let Some(schema) = add_channel_recipient_schema { request = request.body(to_string(&schema).unwrap()); } diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 25995f9..9487100 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -27,7 +27,8 @@ impl Message { request: Client::new() .post(format!("{}/channels/{}/messages", url_api, channel_id)) .header("Authorization", user.token()) - .body(to_string(&message).unwrap()), + .body(to_string(&message).unwrap()) + .header("Content-Type", "application/json"), limit_type: LimitType::Channel(channel_id), }; chorus_request.deserialize_response::(user).await diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index b445876..8a6316f 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -43,6 +43,7 @@ impl types::Channel { request: Client::new() .put(url) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(body), limit_type: LimitType::Channel(channel_id), }; diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index f9b7541..519da12 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -108,7 +108,10 @@ impl ReactionMeta { emoji ); let chorus_request = ChorusRequest { - request: Client::new().put(url).header("Authorization", user.token()), + request: Client::new() + .put(url) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), limit_type: LimitType::Channel(self.channel_id), }; chorus_request.handle_request_as_result(user).await diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 9031563..9c67831 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -24,6 +24,7 @@ impl Guild { request: Client::new() .post(url.clone()) .header("Authorization", user.token.clone()) + .header("Content-Type", "application/json") .body(to_string(&guild_create_schema).unwrap()), limit_type: LimitType::Global, }; @@ -58,7 +59,8 @@ impl Guild { let chorus_request = ChorusRequest { request: Client::new() .post(url.clone()) - .header("Authorization", user.token.clone()), + .header("Authorization", user.token.clone()) + .header("Content-Type", "application/json"), limit_type: LimitType::Global, }; chorus_request.handle_request_as_result(user).await @@ -157,6 +159,7 @@ impl Channel { guild_id )) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(to_string(&schema).unwrap()), limit_type: LimitType::Guild(guild_id), }; diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index dcced7e..f9f02dc 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -53,7 +53,10 @@ impl types::GuildMember { role_id ); let chorus_request = ChorusRequest { - request: Client::new().put(url).header("Authorization", user.token()), + request: Client::new() + .put(url) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), limit_type: LimitType::Guild(guild_id), }; chorus_request.handle_request_as_result(user).await diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index c0893a8..678450c 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -83,6 +83,7 @@ impl types::RoleObject { request: Client::new() .post(url) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(body), limit_type: LimitType::Guild(guild_id), }; @@ -115,6 +116,7 @@ impl types::RoleObject { request: Client::new() .patch(url) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(body), limit_type: LimitType::Guild(guild_id), }; @@ -150,6 +152,7 @@ impl types::RoleObject { request: Client::new() .patch(url) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(body), limit_type: LimitType::Guild(guild_id), }; diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index c32d30a..8742c3f 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -31,6 +31,7 @@ impl UserMeta { if session_id.is_some() { request.request = request .request + .header("Content-Type", "application/json") .body(to_string(session_id.unwrap()).unwrap()); } request.deserialize_response::(self).await @@ -50,7 +51,8 @@ impl UserMeta { self.belongs_to.borrow().urls.api )) .body(to_string(&code).unwrap()) - .header("Authorization", self.token()), + .header("Authorization", self.token()) + .header("Content-Type", "application/json"), limit_type: super::LimitType::Global, } .deserialize_response::(self) @@ -77,6 +79,7 @@ impl UserMeta { channel_id )) .header("Authorization", self.token()) + .header("Content-Type", "application/json") .body(to_string(&create_channel_invite_schema).unwrap()), limit_type: super::LimitType::Channel(channel_id), } diff --git a/src/api/users/channels.rs b/src/api/users/channels.rs index 74f7484..5a33c6c 100644 --- a/src/api/users/channels.rs +++ b/src/api/users/channels.rs @@ -26,6 +26,7 @@ impl UserMeta { request: Client::new() .post(url) .header("Authorization", self.token()) + .header("Content-Type", "application/json") .body(to_string(&create_private_channel_schema).unwrap()), limit_type: LimitType::Global, } diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index f1e586d..355f38c 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -23,6 +23,7 @@ impl UserMeta { guild_id )) .header("Authorization", self.token()) + .header("Content-Type", "application/json") .body(to_string(&lurking).unwrap()), limit_type: crate::api::LimitType::Guild(*guild_id), } diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index 2cf0c6c..e08f414 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -69,6 +69,7 @@ impl UserMeta { request: Client::new() .post(url) .header("Authorization", self.token()) + .header("Content-Type", "application/json") .body(body), limit_type: LimitType::Global, }; diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 1ba4e84..41af054 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -50,7 +50,8 @@ impl UserMeta { let request = Client::new() .patch(format!("{}/users/@me", self.belongs_to.borrow().urls.api)) .body(to_string(&modify_schema).unwrap()) - .header("Authorization", self.token()); + .header("Authorization", self.token()) + .header("Content-Type", "application/json"); let chorus_request = ChorusRequest { request, limit_type: LimitType::default(), @@ -68,7 +69,8 @@ impl UserMeta { "{}/users/@me/delete", self.belongs_to.borrow().urls.api )) - .header("Authorization", self.token()); + .header("Authorization", self.token()) + .header("Content-Type", "application/json"); let chorus_request = ChorusRequest { request, limit_type: LimitType::default(), From ad58b550fb1eb36ed5a3ce8941443b23f44b1260 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Fri, 18 Aug 2023 12:27:39 +0000 Subject: [PATCH 111/237] Minor gateway updates (#188) * Fix TYPING_START not existing * Fix spacebar READY deserialization error --- src/gateway.rs | 3 ++- src/types/events/session.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 9bd4e12..3ac118d 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -628,6 +628,7 @@ impl Gateway { "STAGE_INSTANCE_CREATE" => stage_instance.create, "STAGE_INSTANCE_UPDATE" => stage_instance.update, "STAGE_INSTANCE_DELETE" => stage_instance.delete, + "TYPING_START" => user.typing_start, "USER_UPDATE" => user.update, "USER_GUILD_SETTINGS_UPDATE" => user.guild_settings_update, "VOICE_STATE_UPDATE" => voice.state_update, @@ -972,7 +973,7 @@ mod events { pub update: GatewayEvent, pub guild_settings_update: GatewayEvent, pub presence_update: GatewayEvent, - pub typing_start_event: GatewayEvent, + pub typing_start: GatewayEvent, } #[derive(Default, Debug)] diff --git a/src/types/events/session.rs b/src/types/events/session.rs index 574c5fa..868c8e8 100644 --- a/src/types/events/session.rs +++ b/src/types/events/session.rs @@ -13,7 +13,7 @@ pub struct SessionsReplace { #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// Session info for the current user pub struct Session { - pub activities: Vec, + pub activities: Option>, pub client_info: ClientInfo, pub session_id: String, pub status: String, @@ -24,7 +24,7 @@ pub struct Session { /// {"client":"web","os":"other","version":0} // Note: I don't think this one exists yet? Though I might've made a mistake and this might be a duplicate pub struct ClientInfo { - pub client: String, + pub client: Option, pub os: String, pub version: u8, } From cafa84d41e23ab7795aee0867d72a0f992d4c027 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 18 Aug 2023 20:20:25 +0200 Subject: [PATCH 112/237] Add Todo to every event which needs UpdateMessage --- src/gateway.rs | 72 +++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 3ac118d..2921069 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -568,70 +568,70 @@ impl Gateway { "READY_SUPPLEMENTAL" => session.ready_supplemental, "APPLICATION_COMMAND_PERMISSIONS_UPDATE" => application.command_permissions_update, "AUTO_MODERATION_RULE_CREATE" =>auto_moderation.rule_create, - "AUTO_MODERATION_RULE_UPDATE" =>auto_moderation.rule_update, + "AUTO_MODERATION_RULE_UPDATE" =>auto_moderation.rule_update, // TODO "AUTO_MODERATION_RULE_DELETE" => auto_moderation.rule_delete, "AUTO_MODERATION_ACTION_EXECUTION" => auto_moderation.action_execution, - "CHANNEL_CREATE" => channel.create, + "CHANNEL_CREATE" => channel.create, // TODO "CHANNEL_UPDATE" => channel.update ChannelUpdate: Channel, "CHANNEL_UNREAD_UPDATE" => channel.unread_update, - "CHANNEL_DELETE" => channel.delete, + "CHANNEL_DELETE" => channel.delete, // TODO "CHANNEL_PINS_UPDATE" => channel.pins_update, "CALL_CREATE" => call.create, "CALL_UPDATE" => call.update, "CALL_DELETE" => call.delete, - "THREAD_CREATE" => thread.create, - "THREAD_UPDATE" => thread.update, - "THREAD_DELETE" => thread.delete, - "THREAD_LIST_SYNC" => thread.list_sync, - "THREAD_MEMBER_UPDATE" => thread.member_update, - "THREAD_MEMBERS_UPDATE" => thread.members_update, - "GUILD_CREATE" => guild.create, - "GUILD_UPDATE" => guild.update, - "GUILD_DELETE" => guild.delete, + "THREAD_CREATE" => thread.create, // TODO + "THREAD_UPDATE" => thread.update, // TODO + "THREAD_DELETE" => thread.delete, // TODO + "THREAD_LIST_SYNC" => thread.list_sync, // TODO + "THREAD_MEMBER_UPDATE" => thread.member_update, // TODO + "THREAD_MEMBERS_UPDATE" => thread.members_update, // TODO + "GUILD_CREATE" => guild.create, // TODO + "GUILD_UPDATE" => guild.update, // TODO + "GUILD_DELETE" => guild.delete, // TODO "GUILD_AUDIT_LOG_ENTRY_CREATE" => guild.audit_log_entry_create, "GUILD_BAN_ADD" => guild.ban_add, "GUILD_BAN_REMOVE" => guild.ban_remove, - "GUILD_EMOJIS_UPDATE" => guild.emojis_update, - "GUILD_STICKERS_UPDATE" => guild.stickers_update, + "GUILD_EMOJIS_UPDATE" => guild.emojis_update, // TODO + "GUILD_STICKERS_UPDATE" => guild.stickers_update, // TODO "GUILD_INTEGRATIONS_UPDATE" => guild.integrations_update, "GUILD_MEMBER_ADD" => guild.member_add, "GUILD_MEMBER_REMOVE" => guild.member_remove, - "GUILD_MEMBER_UPDATE" => guild.member_update, - "GUILD_MEMBERS_CHUNK" => guild.members_chunk, + "GUILD_MEMBER_UPDATE" => guild.member_update, // TODO + "GUILD_MEMBERS_CHUNK" => guild.members_chunk, // TODO "GUILD_ROLE_CREATE" => guild.role_create GuildRoleCreate: Guild, "GUILD_ROLE_UPDATE" => guild.role_update GuildRoleUpdate: RoleObject, - "GUILD_ROLE_DELETE" => guild.role_delete, - "GUILD_SCHEDULED_EVENT_CREATE" => guild.role_scheduled_event_create, - "GUILD_SCHEDULED_EVENT_UPDATE" => guild.role_scheduled_event_update, - "GUILD_SCHEDULED_EVENT_DELETE" => guild.role_scheduled_event_delete, + "GUILD_ROLE_DELETE" => guild.role_delete, // TODO + "GUILD_SCHEDULED_EVENT_CREATE" => guild.role_scheduled_event_create, // TODO + "GUILD_SCHEDULED_EVENT_UPDATE" => guild.role_scheduled_event_update, // TODO + "GUILD_SCHEDULED_EVENT_DELETE" => guild.role_scheduled_event_delete, // TODO "GUILD_SCHEDULED_EVENT_USER_ADD" => guild.role_scheduled_event_user_add, "GUILD_SCHEDULED_EVENT_USER_REMOVE" => guild.role_scheduled_event_user_remove, - "PASSIVE_UPDATE_V1" => guild.passive_update_v1, - "INTEGRATION_CREATE" => integration.create, - "INTEGRATION_UPDATE" => integration.update, - "INTEGRATION_DELETE" => integration.delete, - "INTERACTION_CREATE" => interaction.create, - "INVITE_CREATE" => invite.create, - "INVITE_DELETE" => invite.delete, + "PASSIVE_UPDATE_V1" => guild.passive_update_v1, // TODO + "INTEGRATION_CREATE" => integration.create, // TODO + "INTEGRATION_UPDATE" => integration.update, // TODO + "INTEGRATION_DELETE" => integration.delete, // TODO + "INTERACTION_CREATE" => interaction.create, // TODO + "INVITE_CREATE" => invite.create, // TODO + "INVITE_DELETE" => invite.delete, // TODO "MESSAGE_CREATE" => message.create, - "MESSAGE_UPDATE" => message.update, + "MESSAGE_UPDATE" => message.update, // TODO "MESSAGE_DELETE" => message.delete, "MESSAGE_DELETE_BULK" => message.delete_bulk, - "MESSAGE_REACTION_ADD" => message.reaction_add, - "MESSAGE_REACTION_REMOVE" => message.reaction_remove, - "MESSAGE_REACTION_REMOVE_ALL" => message.reaction_remove_all, - "MESSAGE_REACTION_REMOVE_EMOJI" => message.reaction_remove_emoji, + "MESSAGE_REACTION_ADD" => message.reaction_add, // TODO + "MESSAGE_REACTION_REMOVE" => message.reaction_remove, // TODO + "MESSAGE_REACTION_REMOVE_ALL" => message.reaction_remove_all, // TODO + "MESSAGE_REACTION_REMOVE_EMOJI" => message.reaction_remove_emoji, // TODO "MESSAGE_ACK" => message.ack, - "PRESENCE_UPDATE" => user.presence_update, + "PRESENCE_UPDATE" => user.presence_update, // TODO "RELATIONSHIP_ADD" => relationship.add, "RELATIONSHIP_REMOVE" => relationship.remove, "STAGE_INSTANCE_CREATE" => stage_instance.create, - "STAGE_INSTANCE_UPDATE" => stage_instance.update, + "STAGE_INSTANCE_UPDATE" => stage_instance.update, // TODO "STAGE_INSTANCE_DELETE" => stage_instance.delete, "TYPING_START" => user.typing_start, - "USER_UPDATE" => user.update, + "USER_UPDATE" => user.update, // TODO "USER_GUILD_SETTINGS_UPDATE" => user.guild_settings_update, - "VOICE_STATE_UPDATE" => voice.state_update, + "VOICE_STATE_UPDATE" => voice.state_update, // TODO "VOICE_SERVER_UPDATE" => voice.server_update, "WEBHOOKS_UPDATE" => webhooks.update ); From 5f0a04c3458b99ab62e5828f4bbd395cd864ea1b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 18 Aug 2023 20:20:53 +0200 Subject: [PATCH 113/237] Add Arc> --- src/types/entities/invite.rs | 2 +- src/types/entities/message.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/types/entities/invite.rs b/src/types/entities/invite.rs index 1e6befc..842db3f 100644 --- a/src/types/entities/invite.rs +++ b/src/types/entities/invite.rs @@ -21,7 +21,7 @@ pub struct Invite { pub flags: Option, pub guild: Option, pub guild_id: Option, - pub guild_scheduled_event: Option, + pub guild_scheduled_event: Option>>, #[serde(rename = "type")] pub invite_type: Option, pub inviter: Option, diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index f104f97..d7ef01c 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, RwLock}; + use serde::{Deserialize, Serialize}; use crate::types::{ @@ -84,7 +86,7 @@ pub struct MessageInteraction { pub interaction_type: u8, pub name: String, pub user: User, - pub member: Option, + pub member: Option>>, } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] From e1615a4cd35252175cfbb455369f94e98cc76411 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 18 Aug 2023 20:20:58 +0200 Subject: [PATCH 114/237] Remove prints --- src/types/events/guild.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 5fac86b..84ac5b8 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -215,10 +215,8 @@ impl UpdateMessage for GuildRoleUpdate { } fn update(&mut self, object_to_update: Arc>) { - println!("Processing Role Update. Name: {}", self.role.name); let mut write = object_to_update.write().unwrap(); *write = self.role.clone(); - println!("Updated role: Name: {}", write.name); } } From 82d2151f1bb20dc10ed96934c9e278e7012614bf Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 18 Aug 2023 21:29:34 +0200 Subject: [PATCH 115/237] Fix typo --- src/types/entities/channel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index a64b44c..361ecb5 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -16,7 +16,7 @@ use crate::types::{ #[derive(Default, Debug, Serialize, Deserialize, Clone, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] -/// Represents a guild of private channel +/// Represents a guild or private channel /// /// # Reference /// See From d64004b308511f9e35e4c328a19bb97bfbf21edd Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 18 Aug 2023 23:34:00 +0200 Subject: [PATCH 116/237] Make id(&self) return Option --- src/types/entities/auto_moderation.rs | 4 +++- src/types/events/auto_moderation.rs | 14 +++++++++++++- src/types/events/channel.rs | 4 ++-- src/types/events/guild.rs | 8 ++++---- src/types/events/mod.rs | 2 +- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/types/entities/auto_moderation.rs b/src/types/entities/auto_moderation.rs index 77f4fa2..eaec2b0 100644 --- a/src/types/entities/auto_moderation.rs +++ b/src/types/entities/auto_moderation.rs @@ -1,11 +1,13 @@ use std::sync::{Arc, RwLock}; +use crate::gateway::Updateable; +use chorus_macros::Updateable; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use crate::types::utils::Snowflake; -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] /// See pub struct AutoModerationRule { pub id: Snowflake, diff --git a/src/types/events/auto_moderation.rs b/src/types/events/auto_moderation.rs index 0a1600b..376e523 100644 --- a/src/types/events/auto_moderation.rs +++ b/src/types/events/auto_moderation.rs @@ -1,3 +1,5 @@ +use crate::types::JsonField; +use chorus_macros::JsonField; use serde::{Deserialize, Serialize}; use crate::types::{ @@ -5,6 +7,8 @@ use crate::types::{ WebSocketEvent, }; +use super::UpdateMessage; + #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// See pub struct AutoModerationRuleCreate { @@ -14,11 +18,19 @@ pub struct AutoModerationRuleCreate { impl WebSocketEvent for AutoModerationRuleCreate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, JsonField)] /// See pub struct AutoModerationRuleUpdate { #[serde(flatten)] pub rule: AutoModerationRule, + #[serde(skip)] + pub json: String, +} + +impl UpdateMessage for AutoModerationRuleUpdate { + fn id(&self) -> Option { + Some(self.rule.id) + } } impl WebSocketEvent for AutoModerationRuleUpdate {} diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 017c50e..d49cf6e 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -43,8 +43,8 @@ impl UpdateMessage for ChannelUpdate { let mut write = object_to_update.write().unwrap(); *write = self.channel.clone(); } - fn id(&self) -> Snowflake { - self.channel.id + fn id(&self) -> Option { + Some(self.channel.id) } } diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 84ac5b8..0afa9d6 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -180,8 +180,8 @@ pub struct GuildRoleCreate { impl WebSocketEvent for GuildRoleCreate {} impl UpdateMessage for GuildRoleCreate { - fn id(&self) -> Snowflake { - self.guild_id + fn id(&self) -> Option { + Some(self.guild_id) } fn update(&mut self, object_to_update: Arc>) { @@ -210,8 +210,8 @@ pub struct GuildRoleUpdate { impl WebSocketEvent for GuildRoleUpdate {} impl UpdateMessage for GuildRoleUpdate { - fn id(&self) -> Snowflake { - self.role.id + fn id(&self) -> Option { + Some(self.role.id) } fn update(&mut self, object_to_update: Arc>) { diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index 0a296fb..4f287ce 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -122,7 +122,7 @@ where fn update(&mut self, object_to_update: Arc>) { update_object(self.get_json(), object_to_update) } - fn id(&self) -> Snowflake; + fn id(&self) -> Option; } pub(crate) trait JsonField: Clone { From 0b840372e28b9ee0b542c4352d0029d8847c5e1a Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 18 Aug 2023 23:40:01 +0200 Subject: [PATCH 117/237] Handle id().is_none() cases --- src/gateway.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index 2921069..c482fb5 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -1,8 +1,9 @@ use crate::errors::GatewayError; use crate::gateway::events::Events; use crate::types::{ - self, Channel, ChannelUpdate, Composite, Guild, GuildRoleCreate, GuildRoleUpdate, JsonField, - RoleObject, Snowflake, UpdateMessage, WebSocketEvent, + self, AutoModerationRule, AutoModerationRuleUpdate, Channel, ChannelCreate, ChannelUpdate, + Composite, Guild, GuildRoleCreate, GuildRoleUpdate, JsonField, RoleObject, Snowflake, + UpdateMessage, WebSocketEvent, }; use async_trait::async_trait; use std::any::Any; @@ -512,7 +513,13 @@ impl Gateway { $( let mut message: $message_type = message; let store = self.store.lock().await; - if let Some(to_update) = store.get(&message.id()) { + let id = if message.id().is_some() { + message.id().unwrap() + } else { + event.notify(message).await; + return; + }; + if let Some(to_update) = store.get(&id) { let object = to_update.clone(); let inner_object = object.read().unwrap(); if let Some(_) = inner_object.downcast_ref::<$update_type>() { @@ -526,7 +533,7 @@ impl Gateway { message.set_json(json.to_string()); message.update(downcasted.clone()); } else { - warn!("Received {} for {}, but it has been observed to be a different type!", $name, message.id()) + warn!("Received {} for {}, but it has been observed to be a different type!", $name, id) } } )? @@ -568,13 +575,13 @@ impl Gateway { "READY_SUPPLEMENTAL" => session.ready_supplemental, "APPLICATION_COMMAND_PERMISSIONS_UPDATE" => application.command_permissions_update, "AUTO_MODERATION_RULE_CREATE" =>auto_moderation.rule_create, - "AUTO_MODERATION_RULE_UPDATE" =>auto_moderation.rule_update, // TODO + "AUTO_MODERATION_RULE_UPDATE" =>auto_moderation.rule_update AutoModerationRuleUpdate: AutoModerationRule, "AUTO_MODERATION_RULE_DELETE" => auto_moderation.rule_delete, "AUTO_MODERATION_ACTION_EXECUTION" => auto_moderation.action_execution, - "CHANNEL_CREATE" => channel.create, // TODO + "CHANNEL_CREATE" => channel.create, // Could be processed if handle_message returned a Result<(), SomeError>, as channel.guild_id is Option "CHANNEL_UPDATE" => channel.update ChannelUpdate: Channel, "CHANNEL_UNREAD_UPDATE" => channel.unread_update, - "CHANNEL_DELETE" => channel.delete, // TODO + "CHANNEL_DELETE" => channel.delete, // Same as CHANNEL_CREATE "CHANNEL_PINS_UPDATE" => channel.pins_update, "CALL_CREATE" => call.create, "CALL_UPDATE" => call.update, From 6cb28dda929acbb5728bcd41eb5b3d43c6225e97 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 19 Aug 2023 01:13:07 +0200 Subject: [PATCH 118/237] Start implementing some UpdateMessages --- src/gateway.rs | 16 ++++++------ src/types/events/channel.rs | 51 +++++++++++++++++++++++++++++++++++-- src/types/events/thread.rs | 15 +++++++++-- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/gateway.rs b/src/gateway.rs index c482fb5..d3a748c 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -1,9 +1,9 @@ use crate::errors::GatewayError; use crate::gateway::events::Events; use crate::types::{ - self, AutoModerationRule, AutoModerationRuleUpdate, Channel, ChannelCreate, ChannelUpdate, - Composite, Guild, GuildRoleCreate, GuildRoleUpdate, JsonField, RoleObject, Snowflake, - UpdateMessage, WebSocketEvent, + self, AutoModerationRule, AutoModerationRuleUpdate, Channel, ChannelCreate, ChannelDelete, + ChannelUpdate, Composite, Guild, GuildRoleCreate, GuildRoleUpdate, JsonField, RoleObject, + Snowflake, ThreadUpdate, UpdateMessage, WebSocketEvent, }; use async_trait::async_trait; use std::any::Any; @@ -578,16 +578,16 @@ impl Gateway { "AUTO_MODERATION_RULE_UPDATE" =>auto_moderation.rule_update AutoModerationRuleUpdate: AutoModerationRule, "AUTO_MODERATION_RULE_DELETE" => auto_moderation.rule_delete, "AUTO_MODERATION_ACTION_EXECUTION" => auto_moderation.action_execution, - "CHANNEL_CREATE" => channel.create, // Could be processed if handle_message returned a Result<(), SomeError>, as channel.guild_id is Option + "CHANNEL_CREATE" => channel.create ChannelCreate: Guild, "CHANNEL_UPDATE" => channel.update ChannelUpdate: Channel, "CHANNEL_UNREAD_UPDATE" => channel.unread_update, - "CHANNEL_DELETE" => channel.delete, // Same as CHANNEL_CREATE + "CHANNEL_DELETE" => channel.delete ChannelDelete: Guild, "CHANNEL_PINS_UPDATE" => channel.pins_update, "CALL_CREATE" => call.create, "CALL_UPDATE" => call.update, "CALL_DELETE" => call.delete, "THREAD_CREATE" => thread.create, // TODO - "THREAD_UPDATE" => thread.update, // TODO + "THREAD_UPDATE" => thread.update ThreadUpdate: Channel, "THREAD_DELETE" => thread.delete, // TODO "THREAD_LIST_SYNC" => thread.list_sync, // TODO "THREAD_MEMBER_UPDATE" => thread.member_update, // TODO @@ -596,8 +596,8 @@ impl Gateway { "GUILD_UPDATE" => guild.update, // TODO "GUILD_DELETE" => guild.delete, // TODO "GUILD_AUDIT_LOG_ENTRY_CREATE" => guild.audit_log_entry_create, - "GUILD_BAN_ADD" => guild.ban_add, - "GUILD_BAN_REMOVE" => guild.ban_remove, + "GUILD_BAN_ADD" => guild.ban_add, // TODO + "GUILD_BAN_REMOVE" => guild.ban_remove, // TODO "GUILD_EMOJIS_UPDATE" => guild.emojis_update, // TODO "GUILD_STICKERS_UPDATE" => guild.stickers_update, // TODO "GUILD_INTEGRATIONS_UPDATE" => guild.integrations_update, diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index d49cf6e..ae84b79 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -1,6 +1,7 @@ use std::sync::{Arc, RwLock}; use crate::types::events::WebSocketEvent; +use crate::types::Guild; use crate::types::{entities::Channel, JsonField, Snowflake}; use chorus_macros::JsonField; use chrono::{DateTime, Utc}; @@ -18,15 +19,33 @@ pub struct ChannelPinsUpdate { impl WebSocketEvent for ChannelPinsUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct ChannelCreate { #[serde(flatten)] pub channel: Channel, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for ChannelCreate {} +impl UpdateMessage for ChannelCreate { + fn id(&self) -> Option { + self.channel.guild_id + } + + fn update(&mut self, object_to_update: Arc>) { + let mut write = object_to_update.write().unwrap(); + let update = Arc::new(RwLock::new(self.channel.clone())); + if write.channels.is_some() { + write.channels.as_mut().unwrap().push(update); + } else { + write.channels = Some(Vec::from([update])); + } + } +} + #[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct ChannelUpdate { @@ -68,11 +87,39 @@ pub struct ChannelUnreadUpdateObject { impl WebSocketEvent for ChannelUnreadUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct ChannelDelete { #[serde(flatten)] pub channel: Channel, + #[serde(skip)] + pub json: String, +} + +impl UpdateMessage for ChannelDelete { + fn id(&self) -> Option { + self.channel.guild_id + } + + fn update(&mut self, object_to_update: Arc>) { + if self.id().is_none() { + return; + } + let mut write = object_to_update.write().unwrap(); + if write.channels.is_none() { + return; + } + for (iteration, item) in (0_u32..).zip(write.channels.as_mut().unwrap().iter()) { + if item.read().unwrap().id == self.id().unwrap() { + write + .channels + .as_mut() + .unwrap() + .swap_remove(iteration as usize); + return; + } + } + } } impl WebSocketEvent for ChannelDelete {} diff --git a/src/types/events/thread.rs b/src/types/events/thread.rs index 2faecf7..19f1cde 100644 --- a/src/types/events/thread.rs +++ b/src/types/events/thread.rs @@ -1,8 +1,11 @@ +use chorus_macros::JsonField; use serde::{Deserialize, Serialize}; use crate::types::entities::{Channel, ThreadMember}; use crate::types::events::WebSocketEvent; -use crate::types::Snowflake; +use crate::types::{JsonField, Snowflake}; + +use super::UpdateMessage; #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See @@ -13,15 +16,23 @@ pub struct ThreadCreate { impl WebSocketEvent for ThreadCreate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] /// See pub struct ThreadUpdate { #[serde(flatten)] pub thread: Channel, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for ThreadUpdate {} +impl UpdateMessage for ThreadUpdate { + fn id(&self) -> Option { + Some(self.thread.id) + } +} + #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See pub struct ThreadDelete { From 3e9ca3f9ba3c327ba82027e67757178a8297ca4c Mon Sep 17 00:00:00 2001 From: Flori <39242991+bitfl0wer@users.noreply.github.com> Date: Sun, 20 Aug 2023 17:28:11 +0200 Subject: [PATCH 119/237] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9292a46..ac8f177 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Chorus is a Rust library that allows developers to interact with multiple Spaceb ## Contributing +If you'd like to contribute new functionality, check out [The 'Meta'-issues.](https://github.com/polyphony-chat/chorus/issues?q=is%3Aissue+label%3A%22Type%3A+Meta%22+) They contain a comprehensive list of all features which are yet missing for full Discord.com compatibility. If you would like to contribute, please feel free to open an Issue with the idea you have, or a Pull Request. Please keep our [contribution guidelines](https://github.com/polyphony-chat/.github/blob/main/CONTRIBUTION_GUIDELINES.md) in mind. Your contribution might not be accepted, if it violates these guidelines or [our Code of Conduct](https://github.com/polyphony-chat/.github/blob/main/CODE_OF_CONDUCT.md). @@ -133,4 +134,4 @@ accepted, if it violates these guidelines or [our Code of Conduct](https://githu [license-url]: https://github.com/polyphony-chat/chorus/blob/master/LICENSE [Discord]: https://dcbadge.vercel.app/api/server/m3FpcapGDD?style=flat [Discord-invite]: https://discord.com/invite/m3FpcapGDD - \ No newline at end of file + From b53afe855d41814998774280b7a814209d16789d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 18:48:07 +0200 Subject: [PATCH 120/237] Create GuildBanCreateSchema, clean up GuildCreateSchema --- src/types/schema/guild.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index cb0dac8..77c6725 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -2,10 +2,10 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] #[serde(rename_all = "snake_case")] /// Represents the schema which needs to be sent to create a Guild. -/// See: [https://docs.spacebar.chat/routes/#cmp--schemas-guildcreateschema](https://docs.spacebar.chat/routes/#cmp--schemas-guildcreateschema) +/// See: pub struct GuildCreateSchema { pub name: Option, pub region: Option, @@ -15,3 +15,12 @@ pub struct GuildCreateSchema { pub system_channel_id: Option, pub rules_channel_id: Option, } + +#[derive(Debug, Deserialize, Serialize, Default, Clone, Copy, Eq, PartialEq)] +#[serde(rename_all = "snake_case")] +/// Represents the schema which needs to be sent to create a Guild Ban. +/// See: +pub struct GuildBanCreateSchema { + pub delete_message_days: Option, + pub delete_message_seconds: Option, +} From cb216c462df7a61d6b8a1c4e4f646bf32ebf333a Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 18:49:10 +0200 Subject: [PATCH 121/237] Add create_ban Closes "Create Guild Ban #299" --- src/api/guilds/guilds.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 9c67831..d26c069 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -7,8 +7,8 @@ use crate::errors::ChorusError; use crate::errors::ChorusResult; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; -use crate::types::Snowflake; -use crate::types::{Channel, ChannelCreateSchema, Guild, GuildCreateSchema}; +use crate::types::{Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema}; +use crate::types::{GuildBan, Snowflake}; impl Guild { /// Creates a new guild. @@ -137,6 +137,30 @@ impl Guild { let response = chorus_request.deserialize_response::(user).await?; Ok(response) } + + pub async fn create_ban( + guild_id: Snowflake, + user_id: Snowflake, + schema: GuildBanCreateSchema, + user: &mut UserMeta, + ) -> ChorusResult { + let chorus_request = ChorusRequest { + request: Client::new() + .put(format!( + "{}/guilds/{}/bans/{}", + user.belongs_to.borrow().urls.api, + guild_id, + user_id + )) + .header("Authorization", user.token()) + .body(to_string(&schema).unwrap()), + limit_type: LimitType::Guild(guild_id), + }; + let response = chorus_request + .deserialize_response::(user) + .await?; + Ok(response) + } } impl Channel { From 1f6b221413983b474a8918bf889c3593091cc0e4 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 18:55:47 +0200 Subject: [PATCH 122/237] Add "lazy" test for guild_create_ban --- tests/guilds.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/guilds.rs b/tests/guilds.rs index 3d29d43..fef067f 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -1,4 +1,4 @@ -use chorus::types::{Guild, GuildCreateSchema}; +use chorus::types::{CreateChannelInviteSchema, Guild, GuildBanCreateSchema, GuildCreateSchema}; mod common; @@ -31,3 +31,30 @@ async fn get_channels() { println!("{:?}", guild.channels(&mut bundle.user).await.unwrap()); common::teardown(bundle).await; } + +#[tokio::test] +async fn guild_create_ban() { + // TODO: When routes exist to check if user x is on guild y, add this as an assertion to check + // if Spacebar actually bans the user. + let mut bundle = common::setup().await; + let channel = bundle.channel.read().unwrap().clone(); + let mut other_user = bundle.create_user("testuser1312").await; + let user = &mut bundle.user; + let create_channel_invite_schema = CreateChannelInviteSchema::default(); + let guild = bundle.guild.read().unwrap().clone(); + let invite = user + .create_channel_invite(create_channel_invite_schema, channel.id) + .await + .unwrap(); + other_user.accept_invite(&invite.code, None).await.unwrap(); + let other_user_id = other_user.object.read().unwrap().id; + Guild::create_ban( + guild.id, + other_user_id, + GuildBanCreateSchema::default(), + &mut bundle.user, + ) + .await + .unwrap(); + common::teardown(bundle).await +} From 99fed46225067acbf40c9c0b1ec0adb4b57d698f Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 19:26:00 +0200 Subject: [PATCH 123/237] Make ban test a little more meaningful --- tests/guilds.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/guilds.rs b/tests/guilds.rs index fef067f..96e632a 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -56,5 +56,13 @@ async fn guild_create_ban() { ) .await .unwrap(); + assert!(Guild::create_ban( + guild.id, + other_user_id, + GuildBanCreateSchema::default(), + &mut bundle.user, + ) + .await + .is_err()); common::teardown(bundle).await } From dd04b760a4fc90218597b9f02b8e3921b06dd874 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 22:46:44 +0200 Subject: [PATCH 124/237] Add Types --- src/types/entities/guild.rs | 105 +++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 6 deletions(-) diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 3f59055..65fc986 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -14,6 +14,7 @@ use crate::types::{ utils::Snowflake, Composite, }; +use bitflags::bitflags; /// See #[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] @@ -33,7 +34,7 @@ pub struct Guild { #[cfg_attr(feature = "sqlx", sqlx(skip))] #[observe_option_vec] pub channels: Option>>>, - pub default_message_notifications: Option, + pub default_message_notifications: Option, pub description: Option, pub discovery_splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] @@ -57,9 +58,9 @@ pub struct Guild { #[cfg_attr(feature = "sqlx", sqlx(skip))] pub max_stage_video_channel_users: Option, pub max_video_channel_users: Option, - pub mfa_level: Option, + pub mfa_level: Option, pub name: Option, - pub nsfw_level: Option, + pub nsfw_level: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub owner: Option, // True if requesting user is owner @@ -69,7 +70,7 @@ pub struct Guild { pub preferred_locale: Option, pub premium_progress_bar_enabled: Option, pub premium_subscription_count: Option, - pub premium_tier: Option, + pub premium_tier: Option, pub primary_category_id: Option, pub public_updates_channel_id: Option, pub region: Option, @@ -82,11 +83,11 @@ pub struct Guild { pub splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub stickers: Option>, - pub system_channel_flags: Option, + pub system_channel_flags: Option, pub system_channel_id: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub vanity_url_code: Option, - pub verification_level: Option, + pub verification_level: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] #[observe_option_vec] pub voice_states: Option>>>, @@ -199,3 +200,95 @@ pub enum GuildScheduledEventEntityType { pub struct GuildScheduledEventEntityMetadata { pub location: Option, } + +#[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq)] +pub struct VoiceRegion { + id: String, + name: String, + optimal: bool, + deprecated: bool, + custom: bool, +} + +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[repr(u8)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +/// See +pub enum MessageNotificationLevel { + #[default] + AllMessages = 0, + OnlyMentions = 1, +} + +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[repr(u8)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +/// See +pub enum ExplicitContentFilterLevel { + #[default] + Disabled = 0, + MembersWithoutRoles = 1, + AllMembers = 2, +} + +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[repr(u8)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +/// See +pub enum VerificationLevel { + #[default] + None = 0, + Low = 1, + Medium = 2, + High = 3, + VeryHigh = 4, +} + +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[repr(u8)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +/// See +pub enum MFALevel { + #[default] + None = 0, + Elevated = 1, +} + +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[repr(u8)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +/// See +pub enum NSFWLevel { + #[default] + Default = 0, + Explicit = 1, + Safe = 2, + AgeRestricted = 3, +} + +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[repr(u8)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +/// See +pub enum PremiumTier { + #[default] + None = 0, + Tier1 = 1, + Tier2 = 2, + Tier3 = 3, +} + +bitflags! { + #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] + /// # Reference + /// See + pub struct SystemChannelFlags: u64 { + /// Indicates if an app uses the Auto Moderation API + const SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0; + const SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1; + const SUPPRESS_GUILD_REMINDER_NOTIFICATIONS = 1 << 2; + const SUPPRESS_JOIN_NOTIFICATION_REPLIES = 1 << 3; + const SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS = 1 << 4; + const SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS_REPLIES = 1 << 5; + } +} From 09a83f1a1f26cc72c93cc5ff28602092ac26f510 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 22:46:58 +0200 Subject: [PATCH 125/237] Add GuildModifySchema --- src/types/schema/guild.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 77c6725..b0d703b 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; +use crate::types::Snowflake; #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] #[serde(rename_all = "snake_case")] @@ -24,3 +25,20 @@ pub struct GuildBanCreateSchema { pub delete_message_days: Option, pub delete_message_seconds: Option, } + +#[derive(Debug, Deserialize, Serialize, Default, Clone, Eq, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct GuildModifySchema { + pub name: Option, + pub icon: Option>, + pub banner: Option>, + pub home_header: Option>, + pub splash: Option>, + pub discovery_splash: Option>, + pub owner_id: Option, + pub description: Option, + pub region: Option, + pub afk_channel_id: Option, + pub afk_timeout: Option, + pub verification_level: Option, +} From 24891b3fd58b9aa9aa2b8ba7160b4d2452d8717c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 22:52:06 +0200 Subject: [PATCH 126/237] Complete GuildModifySchema --- src/types/schema/guild.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index b0d703b..937c439 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -1,7 +1,11 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; -use crate::types::Snowflake; +use crate::types::types::guild_configuration::GuildFeatures; +use crate::types::{ + ExplicitContentFilterLevel, MessageNotificationLevel, Snowflake, SystemChannelFlags, + VerificationLevel, +}; #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] #[serde(rename_all = "snake_case")] @@ -40,5 +44,15 @@ pub struct GuildModifySchema { pub region: Option, pub afk_channel_id: Option, pub afk_timeout: Option, - pub verification_level: Option, + pub verification_level: Option, + pub default_message_notifications: Option, + pub explicit_content_filter: Option, + pub features: Option>, + pub system_channel_id: Option, + pub system_channel_flags: Option, + pub rules_channel_id: Option, + pub public_updates_channel_id: Option, + pub safety_alerts_channel_id: Option, + pub preferred_locale: Option, + pub premium_progress_bar_enabled: Option, } From 7eee08459bb41ba03125e8fb079032246783e32c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 23:13:34 +0200 Subject: [PATCH 127/237] Add Guild::modify(); --- src/api/guilds/guilds.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index d26c069..85a18b7 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -7,7 +7,9 @@ use crate::errors::ChorusError; use crate::errors::ChorusResult; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; -use crate::types::{Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema}; +use crate::types::{ + Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildModifySchema, +}; use crate::types::{GuildBan, Snowflake}; impl Guild { @@ -161,6 +163,28 @@ impl Guild { .await?; Ok(response) } + + /// # Reference + /// + pub async fn modify( + guild_id: Snowflake, + schema: GuildModifySchema, + user: &mut UserMeta, + ) -> ChorusResult { + let chorus_request = ChorusRequest { + request: Client::new() + .patch(format!( + "{}/guilds/{}", + user.belongs_to.borrow().urls.api, + guild_id, + )) + .header("Authorization", user.token()) + .body(to_string(&schema).unwrap()), + limit_type: LimitType::Guild(guild_id), + }; + let response = chorus_request.deserialize_response::(user).await?; + Ok(response) + } } impl Channel { From 29d5fe947c159424ad1d59b4d7a698e5e00dab93 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 23:24:06 +0200 Subject: [PATCH 128/237] Add modify_guild test --- tests/guilds.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/guilds.rs b/tests/guilds.rs index 96e632a..8ae6596 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -1,4 +1,6 @@ -use chorus::types::{CreateChannelInviteSchema, Guild, GuildBanCreateSchema, GuildCreateSchema}; +use chorus::types::{ + CreateChannelInviteSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildModifySchema, +}; mod common; @@ -66,3 +68,18 @@ async fn guild_create_ban() { .is_err()); common::teardown(bundle).await } + +#[tokio::test] +async fn modify_guild() { + let mut bundle = common::setup().await; + let schema = GuildModifySchema { + name: Some("Mycoolguild".to_string()), + ..Default::default() + }; + let guild_id = bundle.guild.read().unwrap().id; + let result = Guild::modify(guild_id, schema, &mut bundle.user) + .await + .unwrap(); + assert_eq!(result.name.unwrap(), "Mycoolguild".to_string()); + common::teardown(bundle).await +} From 5f532eff019fe6393067bf4c6b2994672d58da9e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 20 Aug 2023 23:24:30 +0200 Subject: [PATCH 129/237] Fix deserialize error --- src/types/entities/guild.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 65fc986..b6f3cd4 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -83,7 +83,7 @@ pub struct Guild { pub splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub stickers: Option>, - pub system_channel_flags: Option, + pub system_channel_flags: Option, pub system_channel_id: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub vanity_url_code: Option, From cfbcb29a95f9ea496be357952fc6900f8ae758ba Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 01:11:22 +0200 Subject: [PATCH 130/237] Modify Guild Channel Positions Fixes #229 --- src/api/channels/channels.rs | 28 +++++++++++++++++++++++++++- src/types/schema/channel.rs | 9 +++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 14c295a..518de59 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -1,7 +1,7 @@ use reqwest::Client; use serde_json::to_string; -use crate::types::AddChannelRecipientSchema; +use crate::types::{AddChannelRecipientSchema, ModifyChannelPositionsSchema}; use crate::{ api::LimitType, errors::{ChorusError, ChorusResult}, @@ -167,4 +167,30 @@ impl Channel { .handle_request_as_result(user) .await } + + /// Modifies the positions of a set of channel objects for the guild. Requires the `MANAGE_CHANNELS` permission. + /// Only channels to be modified are required. + /// + /// # Reference: + /// See + pub async fn modify_positions( + schema: Vec, + guild_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult<()> { + let request = Client::new() + .patch(format!( + "{}/guilds/{}/channels", + user.belongs_to.borrow().urls.api, + guild_id + )) + .header("Authorization", user.token()) + .body(to_string(&schema).unwrap()); + ChorusRequest { + request, + limit_type: LimitType::Guild(guild_id), + } + .handle_request_as_result(user) + .await + } } diff --git a/src/types/schema/channel.rs b/src/types/schema/channel.rs index 27c78ee..dd62f88 100644 --- a/src/types/schema/channel.rs +++ b/src/types/schema/channel.rs @@ -148,3 +148,12 @@ pub struct AddChannelRecipientSchema { pub access_token: Option, pub nick: Option, } + +/// See +#[derive(Debug, Deserialize, Serialize, Clone, Default, PartialOrd, Ord, PartialEq, Eq)] +pub struct ModifyChannelPositionsSchema { + pub id: Snowflake, + pub position: Option, + pub lock_permissions: Option, + pub parent_id: Option, +} From a13f766758493c92bf308e76593aa7cd9e71a69b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 14:00:39 +0200 Subject: [PATCH 131/237] Add search() and search_messages() --- src/api/channels/messages.rs | 91 ++++++++++++++++++++++++++++++++++-- src/api/guilds/messages.rs | 28 +++++++++++ src/api/guilds/mod.rs | 2 + 3 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 src/api/guilds/messages.rs diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 9487100..833ff16 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -1,13 +1,15 @@ use http::header::CONTENT_DISPOSITION; use http::HeaderMap; use reqwest::{multipart, Client}; -use serde_json::to_string; +use serde_json::{from_str, to_string, to_value}; use crate::api::LimitType; -use crate::errors::ChorusResult; +use crate::errors::{ChorusError, ChorusResult}; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; -use crate::types::{Message, MessageSendSchema, Snowflake}; +use crate::types::{ + Message, MessageSearchEndpoint, MessageSearchQuery, MessageSendSchema, Snowflake, +}; impl Message { /// Sends a message in the channel with the provided channel_id. @@ -70,6 +72,89 @@ impl Message { chorus_request.deserialize_response::(user).await } } + + /// Returns messages without the reactions key that match a search query in the guild or channel. + /// The messages that are direct results will have an extra hit key set to true. + /// If operating on a guild channel, this endpoint requires the `READ_MESSAGE_HISTORY` + /// permission to be present on the current user. + /// + /// If the guild/channel you are searching is not yet indexed, the endpoint will return a 202 accepted response. + /// In this case, the method will return a [`ChorusError::InvalidResponse`] error. + /// + /// # Reference: + /// See + pub(crate) async fn search( + endpoint: MessageSearchEndpoint, + query: MessageSearchQuery, + user: &mut UserMeta, + ) -> ChorusResult> { + let limit_type = match &endpoint { + MessageSearchEndpoint::Channel(id) => LimitType::Channel(*id), + MessageSearchEndpoint::GuildChannel(id) => LimitType::Guild(*id), + }; + let request = ChorusRequest { + limit_type, + request: Client::new() + .get(format!( + "{}/{}/messages/search", + &user.belongs_to.borrow().urls.api, + endpoint + )) + .header("Authorization", user.token()) + .body(to_string(&query).unwrap()), + }; + let result = request.send_request(user).await?; + let result_text = result.text().await.unwrap(); + if let Ok(response) = from_str::>(&result_text) { + return Ok(response); + } + if to_value(result_text.clone()).is_err() { + return Err(search_error(result_text)); + } + let result_value = to_value(result_text.clone()).unwrap(); + if !result_value.is_object() { + return Err(search_error(result_text)); + } + let value_map = result_value.as_object().unwrap(); + if !value_map.contains_key("code") || !value_map.contains_key("retry_after") { + return Err(search_error(result_text)); + } + let code = value_map.get("code").unwrap().as_u64().unwrap(); + let retry_after = value_map.get("retry_after").unwrap().as_u64().unwrap(); + Err(ChorusError::NotFound { + error: format!( + "Index not yet available. Try again later. Code: {}. Retry after {}s", + code, retry_after + ), + }) + } + + /// Returns messages without the reactions key that match a search query in the channel. + /// The messages that are direct results will have an extra hit key set to true. + /// If operating on a guild channel, this endpoint requires the `READ_MESSAGE_HISTORY` + /// permission to be present on the current user. + /// + /// If the guild/channel you are searching is not yet indexed, the endpoint will return a 202 accepted response. + /// In this case, the method will return a [`ChorusError::InvalidResponse`] error. + /// + /// # Reference: + /// See + pub async fn search_messages( + channel_id: Snowflake, + query: MessageSearchQuery, + user: &mut UserMeta, + ) -> ChorusResult> { + Message::search(MessageSearchEndpoint::Channel(channel_id), query, user).await + } +} + +fn search_error(result_text: String) -> ChorusError { + ChorusError::InvalidResponse { + error: format!( + "Got unexpected Response, or Response which is not valid JSON. Response: \n{}", + result_text + ), + } } impl UserMeta { diff --git a/src/api/guilds/messages.rs b/src/api/guilds/messages.rs new file mode 100644 index 0000000..72d886c --- /dev/null +++ b/src/api/guilds/messages.rs @@ -0,0 +1,28 @@ +use crate::errors::ChorusResult; +use crate::instance::UserMeta; +use crate::types::{Guild, Message, MessageSearchQuery, Snowflake}; + +impl Guild { + /// Returns messages without the reactions key that match a search query in the guild. + /// The messages that are direct results will have an extra hit key set to true. + /// If operating on a guild channel, this endpoint requires the `READ_MESSAGE_HISTORY` + /// permission to be present on the current user. + /// + /// If the guild/channel you are searching is not yet indexed, the endpoint will return a 202 accepted response. + /// In this case, the method will return a [`ChorusError::InvalidResponse`] error. + /// + /// # Reference: + /// See + pub async fn search_messages( + guild_id: Snowflake, + query: MessageSearchQuery, + user: &mut UserMeta, + ) -> ChorusResult> { + Message::search( + crate::types::MessageSearchEndpoint::GuildChannel(guild_id), + query, + user, + ) + .await + } +} diff --git a/src/api/guilds/mod.rs b/src/api/guilds/mod.rs index 7577479..f1fa039 100644 --- a/src/api/guilds/mod.rs +++ b/src/api/guilds/mod.rs @@ -1,7 +1,9 @@ pub use guilds::*; +pub use messages::*; pub use roles::*; pub use roles::*; pub mod guilds; pub mod member; +pub mod messages; pub mod roles; From 1984f8c5daa8a7807425929e661e7da3cef3040c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 14:01:03 +0200 Subject: [PATCH 132/237] Add MessageSearchEndpoint Enum and MessageSearchQuery schema struct --- src/types/schema/message.rs | 51 ++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/types/schema/message.rs b/src/types/schema/message.rs index e1abdf7..94a5884 100644 --- a/src/types/schema/message.rs +++ b/src/types/schema/message.rs @@ -3,8 +3,9 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::{ AllowedMention, Component, Embed, MessageReference, PartialDiscordFileAttachment, }; +use crate::types::Snowflake; -#[derive(Debug, Default, Deserialize, Serialize)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)] #[serde(rename_all = "snake_case")] pub struct MessageSendSchema { #[serde(rename = "type")] @@ -19,3 +20,51 @@ pub struct MessageSendSchema { pub sticker_ids: Option>, pub attachments: Option>, } + +pub enum MessageSearchEndpoint { + GuildChannel(Snowflake), + Channel(Snowflake), +} + +impl std::fmt::Display for MessageSearchEndpoint { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + MessageSearchEndpoint::Channel(id) => { + write!(f, "channels/{}", &id.to_string()) + } + MessageSearchEndpoint::GuildChannel(id) => { + write!(f, "guilds/{}", &id.to_string()) + } + } + } +} + +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord)] +/// Represents a Message Search Query JSON Body. +/// The `channel_id` field is not applicable when using the `GET /channels/{channel.id}/messages/search` endpoint. +/// +/// # Reference: +/// See +pub struct MessageSearchQuery { + attachment_extension: Option>, + attachment_filename: Option>, + author_id: Option>, + author_type: Option>, + channel_id: Option>, + command_id: Option>, + content: Option, + embed_provider: Option>, + embed_type: Option>, + has: Option>, + include_nsfw: Option, + limit: Option, + link_hostname: Option>, + max_id: Option, + mention_everyone: Option, + mentions: Option>, + min_id: Option, + offset: Option, + pinned: Option, + sort_by: Option, + sort_order: Option, +} From 500ab0e3d0933af1f8012f3f4144d0d24a038ca5 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 14:01:17 +0200 Subject: [PATCH 133/237] Add some missing derives --- src/types/entities/attachment.rs | 2 +- src/types/entities/message.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/types/entities/attachment.rs b/src/types/entities/attachment.rs index 75ec860..59ad53d 100644 --- a/src/types/entities/attachment.rs +++ b/src/types/entities/attachment.rs @@ -31,7 +31,7 @@ pub struct Attachment { pub content: Option>, } -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct PartialDiscordFileAttachment { pub id: Option, pub filename: String, diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index d7ef01c..4b03649 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -114,7 +114,7 @@ pub struct ChannelMention { name: String, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Embed { title: Option, #[serde(rename = "type")] @@ -132,14 +132,14 @@ pub struct Embed { fields: Option>, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct EmbedFooter { text: String, icon_url: Option, proxy_icon_url: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct EmbedImage { url: String, proxy_url: String, @@ -147,7 +147,7 @@ pub struct EmbedImage { width: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct EmbedThumbnail { url: String, proxy_url: Option, @@ -155,7 +155,7 @@ pub struct EmbedThumbnail { width: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] struct EmbedVideo { url: Option, proxy_url: Option, @@ -163,13 +163,13 @@ struct EmbedVideo { width: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct EmbedProvider { name: Option, url: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct EmbedAuthor { name: String, url: Option, @@ -177,7 +177,7 @@ pub struct EmbedAuthor { proxy_icon_url: Option, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct EmbedField { name: String, value: String, From 9ac5925bf9c14d7113a28099e5a7bc8290d93449 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 17:55:29 +0200 Subject: [PATCH 134/237] Make channel_type in ChannelCreateSchema of type enum "ChannelType" --- src/types/entities/channel.rs | 16 ++++++++++++++-- src/types/schema/channel.rs | 3 ++- tests/common/mod.rs | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 361ecb5..84530c9 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -176,10 +176,22 @@ pub struct DefaultReaction { pub emoji_name: Option, } -#[derive(Default, Clone, Copy, Debug, Serialize_repr, Deserialize_repr, PartialEq, Eq, Hash)] +#[derive( + Default, + Clone, + Copy, + Debug, + Serialize_repr, + Deserialize_repr, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, +)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] -#[repr(i32)] +#[repr(u32)] /// # Reference /// See pub enum ChannelType { diff --git a/src/types/schema/channel.rs b/src/types/schema/channel.rs index dd62f88..354459c 100644 --- a/src/types/schema/channel.rs +++ b/src/types/schema/channel.rs @@ -1,6 +1,7 @@ use bitflags::bitflags; use serde::{Deserialize, Serialize}; +use crate::types::ChannelType; use crate::types::{entities::PermissionOverwrite, Snowflake}; #[derive(Debug, Deserialize, Serialize, Default, PartialEq, PartialOrd)] @@ -8,7 +9,7 @@ use crate::types::{entities::PermissionOverwrite, Snowflake}; pub struct ChannelCreateSchema { pub name: String, #[serde(rename = "type")] - pub channel_type: Option, + pub channel_type: Option, pub topic: Option, pub icon: Option, pub bitrate: Option, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 029df2d..2dc0718 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -73,7 +73,7 @@ pub(crate) async fn setup() -> TestBundle { }; let channel_create_schema = ChannelCreateSchema { name: "testchannel".to_string(), - channel_type: Some(0), + channel_type: Some(chorus::types::ChannelType::GuildText), topic: None, icon: None, bitrate: None, From d913b2d97f31a25fc138b460b0f48d4a30bd28e7 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 17:55:53 +0200 Subject: [PATCH 135/237] Implement Default for MessageSearchQuery --- src/types/schema/message.rs | 72 +++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/src/types/schema/message.rs b/src/types/schema/message.rs index 94a5884..e0ee804 100644 --- a/src/types/schema/message.rs +++ b/src/types/schema/message.rs @@ -39,32 +39,60 @@ impl std::fmt::Display for MessageSearchEndpoint { } } -#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord)] /// Represents a Message Search Query JSON Body. /// The `channel_id` field is not applicable when using the `GET /channels/{channel.id}/messages/search` endpoint. /// /// # Reference: /// See pub struct MessageSearchQuery { - attachment_extension: Option>, - attachment_filename: Option>, - author_id: Option>, - author_type: Option>, - channel_id: Option>, - command_id: Option>, - content: Option, - embed_provider: Option>, - embed_type: Option>, - has: Option>, - include_nsfw: Option, - limit: Option, - link_hostname: Option>, - max_id: Option, - mention_everyone: Option, - mentions: Option>, - min_id: Option, - offset: Option, - pinned: Option, - sort_by: Option, - sort_order: Option, + pub attachment_extension: Option>, + pub attachment_filename: Option>, + pub author_id: Option>, + pub author_type: Option>, + pub channel_id: Option>, + pub command_id: Option>, + pub content: Option, + pub embed_provider: Option>, + pub embed_type: Option>, + pub has: Option>, + pub include_nsfw: Option, + pub limit: Option, + pub link_hostname: Option>, + pub max_id: Option, + pub mention_everyone: Option, + pub mentions: Option>, + pub min_id: Option, + pub offset: Option, + pub pinned: Option, + pub sort_by: Option, + pub sort_order: Option, +} + +impl std::default::Default for MessageSearchQuery { + fn default() -> Self { + Self { + attachment_extension: Default::default(), + attachment_filename: Default::default(), + author_id: Default::default(), + author_type: Default::default(), + channel_id: Default::default(), + command_id: Default::default(), + content: Default::default(), + embed_provider: Default::default(), + embed_type: Default::default(), + has: Default::default(), + include_nsfw: Some(false), + limit: Some(25), + link_hostname: Default::default(), + max_id: Default::default(), + mention_everyone: Default::default(), + mentions: Default::default(), + min_id: Default::default(), + offset: Some(0), + pinned: Default::default(), + sort_by: Default::default(), + sort_order: Default::default(), + } + } } From 6e40568b23eb43950658cbf8b3ff4010a86d066a Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 17:56:13 +0200 Subject: [PATCH 136/237] Move search_messages to Channel impl --- src/api/channels/messages.rs | 40 +++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 833ff16..faf6b57 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -8,7 +8,7 @@ use crate::errors::{ChorusError, ChorusResult}; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Message, MessageSearchEndpoint, MessageSearchQuery, MessageSendSchema, Snowflake, + Channel, Message, MessageSearchEndpoint, MessageSearchQuery, MessageSendSchema, Snowflake, }; impl Message { @@ -128,24 +128,6 @@ impl Message { ), }) } - - /// Returns messages without the reactions key that match a search query in the channel. - /// The messages that are direct results will have an extra hit key set to true. - /// If operating on a guild channel, this endpoint requires the `READ_MESSAGE_HISTORY` - /// permission to be present on the current user. - /// - /// If the guild/channel you are searching is not yet indexed, the endpoint will return a 202 accepted response. - /// In this case, the method will return a [`ChorusError::InvalidResponse`] error. - /// - /// # Reference: - /// See - pub async fn search_messages( - channel_id: Snowflake, - query: MessageSearchQuery, - user: &mut UserMeta, - ) -> ChorusResult> { - Message::search(MessageSearchEndpoint::Channel(channel_id), query, user).await - } } fn search_error(result_text: String) -> ChorusError { @@ -174,3 +156,23 @@ impl UserMeta { Message::send(self, channel_id, message).await } } + +impl Channel { + /// Returns messages without the reactions key that match a search query in the channel. + /// The messages that are direct results will have an extra hit key set to true. + /// If operating on a guild channel, this endpoint requires the `READ_MESSAGE_HISTORY` + /// permission to be present on the current user. + /// + /// If the guild/channel you are searching is not yet indexed, the endpoint will return a 202 accepted response. + /// In this case, the method will return a [`ChorusError::InvalidResponse`] error. + /// + /// # Reference: + /// See + pub async fn search_messages( + channel_id: Snowflake, + query: MessageSearchQuery, + user: &mut UserMeta, + ) -> ChorusResult> { + Message::search(MessageSearchEndpoint::Channel(channel_id), query, user).await + } +} From c8378083cf861710c94d6fc1829ee6057322afbd Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 19:22:30 +0200 Subject: [PATCH 137/237] Add json feature to reqwest --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6c15102..e87e747 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ serde_json = { version = "1.0.103", features = ["raw_value"] } serde-aux = "4.2.0" serde_with = "3.0.0" serde_repr = "0.1.14" -reqwest = { version = "0.11.18", features = ["multipart"] } +reqwest = { version = "0.11.18", features = ["multipart", "json"] } url = "2.4.0" chrono = { version = "0.4.26", features = ["serde"] } regex = "1.9.1" From 71dc645210599fa191aa2ed8a8166b9527df618c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 19:23:05 +0200 Subject: [PATCH 138/237] Add search_messages Test --- tests/messages.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/tests/messages.rs b/tests/messages.rs index 417ca54..2854b1d 100644 --- a/tests/messages.rs +++ b/tests/messages.rs @@ -1,7 +1,7 @@ use std::fs::File; use std::io::{BufReader, Read}; -use chorus::types; +use chorus::types::{self, Guild, MessageSearchQuery}; mod common; @@ -53,3 +53,49 @@ async fn send_message_attachment() { bundle.user.send_message(message, channel.id).await.unwrap(); common::teardown(bundle).await } + +#[tokio::test] +async fn search_messages() { + let f = File::open("./README.md").unwrap(); + let mut reader = BufReader::new(f); + let mut buffer = Vec::new(); + let mut bundle = common::setup().await; + + reader.read_to_end(&mut buffer).unwrap(); + + let attachment = types::PartialDiscordFileAttachment { + id: None, + filename: "README.md".to_string(), + description: None, + content_type: None, + size: None, + url: None, + proxy_url: None, + width: None, + height: None, + ephemeral: None, + duration_secs: None, + waveform: None, + content: buffer, + }; + + let message = types::MessageSendSchema { + content: Some("trans rights now".to_string()), + attachments: Some(vec![attachment.clone()]), + ..Default::default() + }; + let channel = bundle.channel.read().unwrap().clone(); + let vec_attach = vec![attachment.clone()]; + let _arg = Some(&vec_attach); + let message = bundle.user.send_message(message, channel.id).await.unwrap(); + let query = MessageSearchQuery { + author_id: Some(Vec::from([bundle.user.object.read().unwrap().id])), + ..Default::default() + }; + let guild_id = bundle.guild.read().unwrap().id; + let query_result = Guild::search_messages(guild_id, query, &mut bundle.user) + .await + .unwrap(); + assert!(!query_result.is_empty()); + assert_eq!(query_result.get(0).unwrap().id, message.id); +} From 36a0730d0b7adf7867c6be1dc2720630687efeb2 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 19:23:27 +0200 Subject: [PATCH 139/237] Correctify search_message Fixes Search Messages #258 --- src/api/channels/messages.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index faf6b57..cc5aa16 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -1,7 +1,7 @@ use http::header::CONTENT_DISPOSITION; use http::HeaderMap; use reqwest::{multipart, Client}; -use serde_json::{from_str, to_string, to_value}; +use serde_json::{from_value, to_string, Value}; use crate::api::LimitType; use crate::errors::{ChorusError, ChorusResult}; @@ -104,20 +104,20 @@ impl Message { .body(to_string(&query).unwrap()), }; let result = request.send_request(user).await?; - let result_text = result.text().await.unwrap(); - if let Ok(response) = from_str::>(&result_text) { - return Ok(response); + let result_json = result.json::().await.unwrap(); + if !result_json.is_object() { + return Err(search_error(result_json.to_string())); } - if to_value(result_text.clone()).is_err() { - return Err(search_error(result_text)); + let value_map = result_json.as_object().unwrap(); + if let Some(messages) = value_map.get("messages") { + if let Ok(response) = from_value::>>(messages.clone()) { + let result_messages: Vec = response.into_iter().flatten().collect(); + return Ok(result_messages); + } } - let result_value = to_value(result_text.clone()).unwrap(); - if !result_value.is_object() { - return Err(search_error(result_text)); - } - let value_map = result_value.as_object().unwrap(); + // The code below might be incorrect. We'll cross that bridge when we come to it if !value_map.contains_key("code") || !value_map.contains_key("retry_after") { - return Err(search_error(result_text)); + return Err(search_error(result_json.to_string())); } let code = value_map.get("code").unwrap().as_u64().unwrap(); let retry_after = value_map.get("retry_after").unwrap().as_u64().unwrap(); From 7b5426519df93505114859cc02d729a5aef7b10d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 20:09:44 +0200 Subject: [PATCH 140/237] Closes #269, #268, #270 --- src/api/channels/messages.rs | 72 +++++++++++++++++++++++++++++++++++ src/types/entities/message.rs | 43 +++++++++++++++++++-- tests/messages.rs | 41 +++++++++++++++++++- 3 files changed, 151 insertions(+), 5 deletions(-) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index cc5aa16..0c3f35b 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -101,6 +101,7 @@ impl Message { endpoint )) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(to_string(&query).unwrap()), }; let result = request.send_request(user).await?; @@ -128,6 +129,77 @@ impl Message { ), }) } + + /// Returns all pinned messages in the channel as a Vector of message objects without the reactions key. + /// # Reference: + /// See: + pub async fn get_sticky( + channel_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult> { + let chorus_request = ChorusRequest { + request: Client::new() + .get(format!( + "{}/channels/{}/pins", + user.belongs_to.borrow().urls.api, + channel_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request + .deserialize_response::>(user) + .await + } + + /// Pins a message in a channel. Requires the `MANAGE_MESSAGES` permission. Returns a 204 empty response on success. + /// The max pinned messages is 50. + /// + /// # Reference: + /// See: + pub async fn sticky( + channel_id: Snowflake, + message_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult<()> { + let chorus_request = ChorusRequest { + request: Client::new() + .put(format!( + "{}/channels/{}/pins/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.handle_request_as_result(user).await + } + + /// Unpins a message in a channel. Requires the `MANAGE_MESSAGES` permission. Returns a 204 empty response on success. + /// # Reference: + /// See: + pub async fn unsticky( + channel_id: Snowflake, + message_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult<()> { + let chorus_request = ChorusRequest { + request: Client::new() + .delete(format!( + "{}/channels/{}/pins/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.handle_request_as_result(user).await + } } fn search_error(result_text: String) -> ChorusError { diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 4b03649..2522268 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -20,7 +20,7 @@ pub struct Message { pub id: Snowflake, pub channel_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub author: PublicUser, + pub author: Option, pub content: Option, pub timestamp: String, pub edited_timestamp: Option, @@ -29,15 +29,15 @@ pub struct Message { #[cfg_attr(feature = "sqlx", sqlx(skip))] pub mentions: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub mention_roles: Vec, + pub mention_roles: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub mention_channels: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - pub attachments: Vec, + pub attachments: Option>, #[cfg(feature = "sqlx")] pub embeds: Vec>, #[cfg(not(feature = "sqlx"))] - pub embeds: Vec, + pub embeds: Option>, #[cfg(feature = "sqlx")] pub reactions: Option>>, #[cfg(not(feature = "sqlx"))] @@ -69,6 +69,41 @@ pub struct Message { pub role_subscription_data: Option, } +impl PartialEq for Message { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + && self.channel_id == other.channel_id + && self.author == other.author + && self.content == other.content + && self.timestamp == other.timestamp + && self.edited_timestamp == other.edited_timestamp + && self.tts == other.tts + && self.mention_everyone == other.mention_everyone + && self.mentions == other.mentions + && self.mention_roles == other.mention_roles + && self.mention_channels == other.mention_channels + && self.attachments == other.attachments + && self.embeds == other.embeds + && self.embeds == other.embeds + && self.nonce == other.nonce + && self.pinned == other.pinned + && self.webhook_id == other.webhook_id + && self.message_type == other.message_type + && self.activity == other.activity + && self.activity == other.activity + && self.application_id == other.application_id + && self.message_reference == other.message_reference + && self.message_reference == other.message_reference + && self.flags == other.flags + && self.referenced_message == other.referenced_message + && self.thread == other.thread + && self.components == other.components + && self.sticker_items == other.sticker_items + && self.position == other.position + && self.role_subscription_data == other.role_subscription_data + } +} + #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] /// # Reference /// See diff --git a/tests/messages.rs b/tests/messages.rs index 2854b1d..43f8c9a 100644 --- a/tests/messages.rs +++ b/tests/messages.rs @@ -1,7 +1,7 @@ use std::fs::File; use std::io::{BufReader, Read}; -use chorus::types::{self, Guild, MessageSearchQuery}; +use chorus::types::{self, Guild, Message, MessageSearchQuery}; mod common; @@ -99,3 +99,42 @@ async fn search_messages() { assert!(!query_result.is_empty()); assert_eq!(query_result.get(0).unwrap().id, message.id); } + +#[tokio::test] +async fn test_stickies() { + let mut bundle = common::setup().await; + let message = types::MessageSendSchema { + content: Some("A Message!".to_string()), + ..Default::default() + }; + let channel = bundle.channel.read().unwrap().clone(); + let message = bundle.user.send_message(message, channel.id).await.unwrap(); + assert_eq!( + Message::get_sticky(channel.id, &mut bundle.user) + .await + .unwrap(), + Vec::::new() + ); + Message::sticky(channel.id, message.id, &mut bundle.user) + .await + .unwrap(); + assert_eq!( + Message::get_sticky(channel.id, &mut bundle.user) + .await + .unwrap() + .get(0) + .unwrap() + .id, + message.id + ); + Message::unsticky(channel.id, message.id, &mut bundle.user) + .await + .unwrap(); + assert_eq!( + Message::get_sticky(channel.id, &mut bundle.user) + .await + .unwrap(), + Vec::::new() + ); + common::teardown(bundle).await +} From fd3a3ee83614cb2fe5c5622e2815d5b9335c6e6d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 21:27:31 +0200 Subject: [PATCH 141/237] Add message: get --- src/api/channels/messages.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 0c3f35b..60d6a97 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -200,6 +200,30 @@ impl Message { }; chorus_request.handle_request_as_result(user).await } + + /// Returns a specific message object in the channel. + /// If operating on a guild channel, this endpoint requires the `READ_MESSAGE_HISTORY` permission to be present on the current user. + /// # Reference: + /// See: + pub async fn get( + channel_id: Snowflake, + message_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult { + let chorus_request = ChorusRequest { + request: Client::new() + .get(format!( + "{}/channels/{}/messages/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.deserialize_response::(user).await + } } fn search_error(result_text: String) -> ChorusError { From d751c92778fb9de9edd7cde5f37d0e32c06f976e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 21:55:24 +0200 Subject: [PATCH 142/237] Create Greet Message --- src/api/channels/messages.rs | 26 +++++++++++++++++++++++++- src/types/entities/message.rs | 6 +++--- src/types/schema/message.rs | 7 +++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 60d6a97..538cae6 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -8,7 +8,8 @@ use crate::errors::{ChorusError, ChorusResult}; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, Message, MessageSearchEndpoint, MessageSearchQuery, MessageSendSchema, Snowflake, + Channel, CreateGreetMessage, Message, MessageSearchEndpoint, MessageSearchQuery, + MessageSendSchema, Snowflake, }; impl Message { @@ -224,6 +225,29 @@ impl Message { }; chorus_request.deserialize_response::(user).await } + + /// Posts a greet message to a channel. This endpoint requires the channel is a DM channel or you reply to a system message. + /// # Reference: + /// See: + pub async fn create_greet( + channel_id: Snowflake, + schema: CreateGreetMessage, + user: &mut UserMeta, + ) -> ChorusResult { + let chorus_request = ChorusRequest { + request: Client::new() + .post(format!( + "{}/channels/{}/messages/greet", + user.belongs_to.borrow().urls.api, + channel_id, + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(to_string(&schema).unwrap()), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.deserialize_response::(user).await + } } fn search_error(result_text: String) -> ChorusError { diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 2522268..f59cdc5 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -104,7 +104,7 @@ impl PartialEq for Message { } } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Eq, Ord, PartialOrd)] /// # Reference /// See pub struct MessageReference { @@ -124,7 +124,7 @@ pub struct MessageInteraction { pub member: Option>>, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Eq, PartialOrd, Ord)] pub struct AllowedMention { parse: Vec, roles: Vec, @@ -132,7 +132,7 @@ pub struct AllowedMention { replied_user: bool, } -#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, Eq, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum AllowedMentionType { Roles, diff --git a/src/types/schema/message.rs b/src/types/schema/message.rs index e0ee804..bf9cddc 100644 --- a/src/types/schema/message.rs +++ b/src/types/schema/message.rs @@ -96,3 +96,10 @@ impl std::default::Default for MessageSearchQuery { } } } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct CreateGreetMessage { + pub sticker_ids: Vec, + pub allowed_mentions: Option, + pub message_reference: Option, +} From 54c5cc6cc2b704023e15d007434c378ca1e2c3bd Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 22:06:19 +0200 Subject: [PATCH 143/237] Add message acknowledge endpoint --- src/api/channels/messages.rs | 36 +++++++++++++++++++++++++++++++++++- src/types/schema/message.rs | 7 +++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 538cae6..36545ac 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -8,7 +8,7 @@ use crate::errors::{ChorusError, ChorusResult}; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, CreateGreetMessage, Message, MessageSearchEndpoint, MessageSearchQuery, + Channel, CreateGreetMessage, Message, MessageAck, MessageSearchEndpoint, MessageSearchQuery, MessageSendSchema, Snowflake, }; @@ -248,6 +248,40 @@ impl Message { }; chorus_request.deserialize_response::(user).await } + + /// Sets the channel's latest acknowledged message (marks a message as read) for the current user. + /// The message ID parameter does not need to be a valid message ID, but it must be a valid snowflake. + /// If the message ID is being set to a message sent prior to the latest acknowledged one, + /// manual should be true or the resulting read state update should be ignored by clients (but is still saved), resulting in undefined behavior. + /// In this case, mention_count should also be set to the amount of mentions unacknowledged as it is not automatically calculated by Discord. + /// + /// Returns an optional token, which can be used as the new `ack` token for following `ack`s. + /// + /// # Reference: + /// See: + pub async fn acknowledge( + channel_id: Snowflake, + message_id: Snowflake, + schema: MessageAck, + user: &mut UserMeta, + ) -> ChorusResult> { + let chorus_request = ChorusRequest { + request: Client::new() + .post(format!( + "{}/channels/{}/messages/{}/ack", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(to_string(&schema).unwrap()), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request + .deserialize_response::>(user) + .await + } } fn search_error(result_text: String) -> ChorusError { diff --git a/src/types/schema/message.rs b/src/types/schema/message.rs index bf9cddc..7603555 100644 --- a/src/types/schema/message.rs +++ b/src/types/schema/message.rs @@ -103,3 +103,10 @@ pub struct CreateGreetMessage { pub allowed_mentions: Option, pub message_reference: Option, } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct MessageAck { + pub token: Option, + pub manual: Option, + pub mention_count: Option, +} From 852d784bd5cfbd7d2ff1c8eda08cb776339fe439 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 22:10:12 +0200 Subject: [PATCH 144/237] Add crosspost endpoint --- src/api/channels/messages.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 36545ac..9a6687d 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -282,6 +282,29 @@ impl Message { .deserialize_response::>(user) .await } + + /// Crossposts a message in a News Channel to following channels. + /// This endpoint requires the `SEND_MESSAGES` permission, if the current user sent the message, + /// or additionally the `MANAGE_MESSAGES` permission, for all other messages, to be present for the current user. + pub async fn crosspost( + channel_id: Snowflake, + message_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult { + let chorus_request = ChorusRequest { + request: Client::new() + .post(format!( + "{}/channels/{}/messages/{}/crosspost", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.deserialize_response::(user).await + } } fn search_error(result_text: String) -> ChorusError { From f85cde71b47b10b3c40d05adb05c3dbe02afe8e2 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 22:16:07 +0200 Subject: [PATCH 145/237] Add Hide from guild feed endpoint --- src/api/channels/messages.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 9a6687d..1eec276 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -286,6 +286,9 @@ impl Message { /// Crossposts a message in a News Channel to following channels. /// This endpoint requires the `SEND_MESSAGES` permission, if the current user sent the message, /// or additionally the `MANAGE_MESSAGES` permission, for all other messages, to be present for the current user. + /// + /// # Reference: + /// See pub async fn crosspost( channel_id: Snowflake, message_id: Snowflake, @@ -305,6 +308,30 @@ impl Message { }; chorus_request.deserialize_response::(user).await } + + /// Hides a message from the feed of the guild the channel belongs to. Returns a 204 empty response on success. + /// + /// # Reference: + /// See + pub async fn hide_from_guild_feed( + channel_id: Snowflake, + message_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult<()> { + let chorus_request = ChorusRequest { + request: Client::new() + .delete(format!( + "{}/channels/{}/messages/{}/hide-guild-feed", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.handle_request_as_result(user).await + } } fn search_error(result_text: String) -> ChorusError { From a8f37ea2018a0ca3af019b97cc880e6f1cf83852 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 22:27:09 +0200 Subject: [PATCH 146/237] Add Modify Message endpoint --- src/api/channels/messages.rs | 36 ++++++++++++++++++++++-- src/types/entities/attachment.rs | 2 +- src/types/entities/emoji.rs | 47 ++++++++++++++++++++++++++++++++ src/types/entities/message.rs | 20 +++++++------- src/types/schema/message.rs | 15 +++++++++- 5 files changed, 106 insertions(+), 14 deletions(-) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 1eec276..05680b9 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -8,8 +8,8 @@ use crate::errors::{ChorusError, ChorusResult}; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, CreateGreetMessage, Message, MessageAck, MessageSearchEndpoint, MessageSearchQuery, - MessageSendSchema, Snowflake, + Channel, CreateGreetMessage, Message, MessageAck, MessageModifySchema, MessageSearchEndpoint, + MessageSearchQuery, MessageSendSchema, Snowflake, }; impl Message { @@ -332,6 +332,38 @@ impl Message { }; chorus_request.handle_request_as_result(user).await } + + /// Edits a previously sent message. All fields can be edited by the original message author. + /// Other users can only edit flags and only if they have the MANAGE_MESSAGES permission in the corresponding channel. + /// When specifying flags, ensure to include all previously set flags/bits in addition to ones that you are modifying. + /// When the content field is edited, the mentions array in the message object will be reconstructed from scratch based on the new content. + /// The allowed_mentions field of the edit request controls how this happens. + /// If there is no explicit allowed_mentions in the edit request, the content will be parsed with default allowances, that is, + /// without regard to whether or not an allowed_mentions was present in the request that originally created the message. + /// + /// # Reference: + /// See: + pub async fn modify( + channel_id: Snowflake, + message_id: Snowflake, + schema: MessageModifySchema, + user: &mut UserMeta, + ) -> ChorusResult { + let chorus_request = ChorusRequest { + request: Client::new() + .patch(format!( + "{}/channels/{}/messages/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(to_string(&schema).unwrap()), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.deserialize_response::(user).await + } } fn search_error(result_text: String) -> ChorusError { diff --git a/src/types/entities/attachment.rs b/src/types/entities/attachment.rs index 59ad53d..ffbc520 100644 --- a/src/types/entities/attachment.rs +++ b/src/types/entities/attachment.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, PartialOrd)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 68700e6..fddef8c 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -26,3 +26,50 @@ pub struct Emoji { pub animated: Option, pub available: Option, } + +impl PartialEq for Emoji { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + && self.name == other.name + && self.roles == other.roles + && self.roles == other.roles + && self.require_colons == other.require_colons + && self.managed == other.managed + && self.animated == other.animated + && self.available == other.available + } +} + +impl PartialOrd for Emoji { + fn partial_cmp(&self, other: &Self) -> Option { + match self.id.partial_cmp(&other.id) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.name.partial_cmp(&other.name) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.roles.partial_cmp(&other.roles) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.roles.partial_cmp(&other.roles) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.require_colons.partial_cmp(&other.require_colons) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.managed.partial_cmp(&other.managed) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.animated.partial_cmp(&other.animated) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + self.available.partial_cmp(&other.available) + } +} diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index f59cdc5..27a8857 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -149,7 +149,7 @@ pub struct ChannelMention { name: String, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, PartialOrd)] pub struct Embed { title: Option, #[serde(rename = "type")] @@ -167,14 +167,14 @@ pub struct Embed { fields: Option>, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct EmbedFooter { text: String, icon_url: Option, proxy_icon_url: Option, } -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, PartialOrd, Ord)] pub struct EmbedImage { url: String, proxy_url: String, @@ -182,7 +182,7 @@ pub struct EmbedImage { width: Option, } -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, PartialOrd, Ord)] pub struct EmbedThumbnail { url: String, proxy_url: Option, @@ -190,7 +190,7 @@ pub struct EmbedThumbnail { width: Option, } -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, PartialOrd, Ord)] struct EmbedVideo { url: Option, proxy_url: Option, @@ -198,13 +198,13 @@ struct EmbedVideo { width: Option, } -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, PartialOrd, Ord)] pub struct EmbedProvider { name: Option, url: Option, } -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, PartialOrd, Ord)] pub struct EmbedAuthor { name: String, url: Option, @@ -212,14 +212,14 @@ pub struct EmbedAuthor { proxy_icon_url: Option, } -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, PartialOrd, Ord)] pub struct EmbedField { name: String, value: String, inline: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialOrd, PartialEq)] pub struct Reaction { pub count: u32, pub burst_count: u32, @@ -229,7 +229,7 @@ pub struct Reaction { pub emoji: Emoji, } -#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, Eq, PartialOrd, Ord)] pub enum Component { ActionRow = 1, Button = 2, diff --git a/src/types/schema/message.rs b/src/types/schema/message.rs index 7603555..d430e2a 100644 --- a/src/types/schema/message.rs +++ b/src/types/schema/message.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::{ AllowedMention, Component, Embed, MessageReference, PartialDiscordFileAttachment, }; -use crate::types::Snowflake; +use crate::types::{Attachment, Snowflake}; #[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)] #[serde(rename_all = "snake_case")] @@ -110,3 +110,16 @@ pub struct MessageAck { pub manual: Option, pub mention_count: Option, } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)] +pub struct MessageModifySchema { + content: Option, + embeds: Option>, + embed: Option, + allowed_mentions: Option, + components: Option>, + flags: Option, + files: Option>, + payload_json: Option, + attachments: Option>, +} From a23363e0a38b8a8f85d7d98fd1b4dd1a4091e7cc Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 22:32:48 +0200 Subject: [PATCH 147/237] add delete and bulk_delete endpoints --- src/api/channels/messages.rs | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 05680b9..c0f6d7e 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -364,6 +364,62 @@ impl Message { }; chorus_request.deserialize_response::(user).await } + + /// Deletes a message. If operating on a guild channel and trying to delete a message that was not sent by the current user, + /// this endpoint requires the `MANAGE_MESSAGES` permission. Returns a 204 empty response on success. + pub async fn delete( + channel_id: Snowflake, + message_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult<()> { + let chorus_request = ChorusRequest { + request: Client::new() + .delete(format!( + "{}/channels/{}/messages/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.handle_request_as_result(user).await + } + + /// Deletes multiple messages in a single request. This endpoint can only be used on guild channels and requires the MANAGE_MESSAGES permission. + /// Returns a 204 empty response on success. + /// + /// **This endpoint will not delete messages older than 2 weeks, and will fail if any message provided is older than that or if any duplicate message IDs are provided.** + /// + /// **This endpoint is not usable by user accounts.** (At least according to Discord.com. Spacebar behaviour may differ.) + /// + /// # Reference: + /// See: + pub async fn bulk_delete( + channel_id: Snowflake, + messages: Vec, + user: &mut UserMeta, + ) -> ChorusResult<()> { + if messages.len() < 2 { + return Err(ChorusError::InvalidArguments { + error: "`messages` must contain at least 2 entries.".to_string(), + }); + } + let chorus_request = ChorusRequest { + request: Client::new() + .post(format!( + "{}/channels/{}/messages/bulk-delete", + user.belongs_to.borrow().urls.api, + channel_id, + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(to_string(&messages).unwrap()), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.handle_request_as_result(user).await + } } fn search_error(result_text: String) -> ChorusError { From 9e3bf947c1af796b311b09c4dde140835b11c558 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 22:34:37 +0200 Subject: [PATCH 148/237] Add acknowledge_pinned endpoint --- src/api/channels/messages.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index c0f6d7e..053ee75 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -420,6 +420,28 @@ impl Message { }; chorus_request.handle_request_as_result(user).await } + + /// Acknowledges the currently pinned messages in a channel. Returns a 204 empty response on success. + /// + /// # Reference: + /// See: + pub async fn acknowledge_pinned( + channel_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult<()> { + let chorus_request = ChorusRequest { + request: Client::new() + .post(format!( + "{}/channels/{}/pins/ack", + user.belongs_to.borrow().urls.api, + channel_id, + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Channel(channel_id), + }; + chorus_request.handle_request_as_result(user).await + } } fn search_error(result_text: String) -> ChorusError { From 0c62bf983679ec9af62db7e3e7e8b742a7105c8b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 22 Aug 2023 22:40:36 +0200 Subject: [PATCH 149/237] Fix clippy lint --- src/types/entities/emoji.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index fddef8c..d80e487 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -29,14 +29,13 @@ pub struct Emoji { impl PartialEq for Emoji { fn eq(&self, other: &Self) -> bool { - self.id == other.id - && self.name == other.name - && self.roles == other.roles - && self.roles == other.roles - && self.require_colons == other.require_colons - && self.managed == other.managed - && self.animated == other.animated - && self.available == other.available + !(self.id != other.id + || self.name != other.name + || self.roles != other.roles + || self.require_colons != other.require_colons + || self.managed != other.managed + || self.animated != other.animated + || self.available != other.available) } } From 9db9d2a51238db26b3685efd1246ab1fc89b60b3 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 23 Aug 2023 00:08:43 +0200 Subject: [PATCH 150/237] Add get user guilds endpoint --- src/api/users/guilds.rs | 27 ++++++++++++++++++++++++++- src/types/schema/guild.rs | 21 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index 355f38c..e4ffbe0 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -1,10 +1,11 @@ use reqwest::Client; use serde_json::to_string; +use crate::api::LimitType; use crate::errors::ChorusResult; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; -use crate::types::Snowflake; +use crate::types::{GetUserGuildSchema, Guild, Snowflake}; impl UserMeta { /// Leaves a given guild. @@ -30,4 +31,28 @@ impl UserMeta { .handle_request_as_result(self) .await } + + /// Returns a list of user guild objects representing the guilds the current user is a member of. + /// This endpoint returns 200 guilds by default + /// + /// # Reference: + /// See: + pub async fn get_guilds( + &mut self, + query: Option, + ) -> ChorusResult> { + let url = format!("{}/users/@me/guilds", self.belongs_to.borrow().urls.api,); + let chorus_request = ChorusRequest { + request: Client::new() + .get(url) + .header("Authorization", self.token()) + .header("Content-Type", "application/json") + .body(to_string(&query).unwrap()), + + limit_type: LimitType::Global, + }; + chorus_request + .deserialize_response::>(self) + .await + } } diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 937c439..75452df 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -1,3 +1,5 @@ +use std::default; + use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; @@ -56,3 +58,22 @@ pub struct GuildModifySchema { pub preferred_locale: Option, pub premium_progress_bar_enabled: Option, } + +#[derive(Debug, Deserialize, Serialize, Clone, Eq, PartialEq, Ord, PartialOrd)] +pub struct GetUserGuildSchema { + pub before: Option, + pub after: Option, + pub limit: Option, + pub with_counts: Option, +} + +impl std::default::Default for GetUserGuildSchema { + fn default() -> Self { + Self { + before: Default::default(), + after: Default::default(), + limit: Some(200), + with_counts: Some(false), + } + } +} From 5ed2f0f2c315c2ff378dfc29376cb0dd67dfd870 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 24 Aug 2023 21:05:39 +0200 Subject: [PATCH 151/237] add get guild preview route --- src/api/guilds/guilds.rs | 29 +++++++++++++++- src/lib.rs | 9 +++++ src/types/entities/sticker.rs | 64 ++++++++++++++++++++++++++++++++++- src/types/schema/guild.rs | 20 +++++++++-- 4 files changed, 118 insertions(+), 4 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 85a18b7..389c08d 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -8,7 +8,8 @@ use crate::errors::ChorusResult; use crate::instance::UserMeta; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildModifySchema, + Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, + GuildModifySchema, GuildPreview, MFALevel, }; use crate::types::{GuildBan, Snowflake}; @@ -179,12 +180,38 @@ impl Guild { guild_id, )) .header("Authorization", user.token()) + .header("Content-Type", "application/json") .body(to_string(&schema).unwrap()), limit_type: LimitType::Guild(guild_id), }; let response = chorus_request.deserialize_response::(user).await?; Ok(response) } + + /// Returns a guild preview object for the given guild ID. If the user is not in the guild, the guild must be discoverable. + /// # Reference: + /// + /// See + pub async fn get_preview( + guild_id: Snowflake, + user: &mut UserMeta, + ) -> ChorusResult { + let chorus_request = ChorusRequest { + request: Client::new() + .patch(format!( + "{}/guilds/{}/preview", + user.belongs_to.borrow().urls.api, + guild_id, + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"), + limit_type: LimitType::Guild(guild_id), + }; + let response = chorus_request + .deserialize_response::(user) + .await?; + Ok(response) + } } impl Channel { diff --git a/src/lib.rs b/src/lib.rs index 6563bed..7a957dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,6 +74,15 @@ impl UrlBundle { } } +/// Unwraps an `Option`. Returns an empty string if the String is `None`, or the String contents +/// if it is `Some`. +pub(crate) fn unwrap_empty_if_none(string: Option) -> String { + match string { + Some(str) => str, + None => "".to_string(), + } +} + #[cfg(test)] mod lib { use super::*; diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index 5413112..c2cdb46 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::User, utils::Snowflake}; -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// Represents a sticker that can be sent in messages. /// @@ -28,6 +28,68 @@ pub struct Sticker { pub sort_value: Option, } +impl PartialEq for Sticker { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + && self.pack_id == other.pack_id + && self.name == other.name + && self.description == other.description + && self.tags == other.tags + && self.asset == other.asset + && self.sticker_type == other.sticker_type + && self.format_type == other.format_type + && self.available == other.available + && self.guild_id == other.guild_id + && self.sort_value == other.sort_value + } +} + +impl PartialOrd for Sticker { + fn partial_cmp(&self, other: &Self) -> Option { + match self.id.partial_cmp(&other.id) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.pack_id.partial_cmp(&other.pack_id) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.name.partial_cmp(&other.name) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.description.partial_cmp(&other.description) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.tags.partial_cmp(&other.tags) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.asset.partial_cmp(&other.asset) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.sticker_type.partial_cmp(&other.sticker_type) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.format_type.partial_cmp(&other.format_type) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.available.partial_cmp(&other.available) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + match self.guild_id.partial_cmp(&other.guild_id) { + Some(core::cmp::Ordering::Equal) => {} + ord => return ord, + } + self.sort_value.partial_cmp(&other.sort_value) + } +} + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] /// A partial sticker object. /// diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 75452df..2622796 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -5,8 +5,8 @@ use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; use crate::types::types::guild_configuration::GuildFeatures; use crate::types::{ - ExplicitContentFilterLevel, MessageNotificationLevel, Snowflake, SystemChannelFlags, - VerificationLevel, + Emoji, ExplicitContentFilterLevel, MessageNotificationLevel, Snowflake, Sticker, + SystemChannelFlags, VerificationLevel, }; #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] @@ -77,3 +77,19 @@ impl std::default::Default for GetUserGuildSchema { } } } + +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, PartialOrd)] +pub struct GuildPreview { + pub id: Snowflake, + pub name: String, + pub icon: Option, + pub description: Option, + pub splash: Option, + pub discovery_splash: Option, + pub home_header: Option, + pub features: Vec, + pub emojis: Vec, + pub stickers: Vec, + pub approximate_member_count: u32, + pub approximate_presence_count: u32, +} From fb7e33c0ec4fe1517623efd3f1dba612322627eb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 24 Aug 2023 21:06:28 +0200 Subject: [PATCH 152/237] Change `UserMeta` to `ChorusUser` --- src/api/auth/login.rs | 8 ++++---- src/api/auth/register.rs | 10 +++++----- src/api/channels/channels.rs | 16 ++++++++-------- src/api/channels/messages.rs | 34 ++++++++++++++++----------------- src/api/channels/permissions.rs | 6 +++--- src/api/channels/reactions.rs | 14 +++++++------- src/api/guilds/guilds.rs | 18 ++++++++--------- src/api/guilds/member.rs | 8 ++++---- src/api/guilds/messages.rs | 4 ++-- src/api/guilds/roles.rs | 12 ++++++------ src/api/invites/mod.rs | 4 ++-- src/api/users/channels.rs | 4 ++-- src/api/users/guilds.rs | 4 ++-- src/api/users/relationships.rs | 4 ++-- src/api/users/users.rs | 10 +++++----- src/instance.rs | 12 ++++++------ src/ratelimiter.rs | 12 ++++++------ tests/common/mod.rs | 10 +++++----- 18 files changed, 95 insertions(+), 95 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 34a873b..d5d96e6 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -8,7 +8,7 @@ use serde_json::to_string; use crate::api::LimitType; use crate::errors::ChorusResult; use crate::gateway::Gateway; -use crate::instance::{Instance, UserMeta}; +use crate::instance::{ChorusUser, Instance}; use crate::ratelimiter::ChorusRequest; use crate::types::{GatewayIdentifyPayload, LoginResult, LoginSchema}; @@ -17,7 +17,7 @@ impl Instance { /// /// # Reference /// See - pub async fn login_account(&mut self, login_schema: &LoginSchema) -> ChorusResult { + pub async fn login_account(&mut self, login_schema: &LoginSchema) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/login"; let chorus_request = ChorusRequest { request: Client::new() @@ -30,7 +30,7 @@ impl Instance { // request (since login is an instance wide limit), which is why we are just cloning the // instances' limits to pass them on as user_rate_limits later. let mut shell = - UserMeta::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; + ChorusUser::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; let login_result = chorus_request .deserialize_response::(&mut shell) .await?; @@ -42,7 +42,7 @@ impl Instance { let gateway = Gateway::new(self.urls.wss.clone()).await.unwrap(); identify.token = login_result.token.clone(); gateway.send_identify(identify).await; - let user = UserMeta::new( + let user = ChorusUser::new( Rc::new(RefCell::new(self.clone())), login_result.token, self.clone_limits_if_some(), diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index b4350d2..43292d9 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -9,7 +9,7 @@ use crate::types::GatewayIdentifyPayload; use crate::{ api::policies::instance::LimitType, errors::ChorusResult, - instance::{Instance, Token, UserMeta}, + instance::{ChorusUser, Instance, Token}, ratelimiter::ChorusRequest, types::RegisterSchema, }; @@ -22,7 +22,7 @@ impl Instance { pub async fn register_account( &mut self, register_schema: &RegisterSchema, - ) -> ChorusResult { + ) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/register"; let chorus_request = ChorusRequest { request: Client::new() @@ -35,7 +35,7 @@ impl Instance { // request (since register is an instance wide limit), which is why we are just cloning // the instances' limits to pass them on as user_rate_limits later. let mut shell = - UserMeta::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; + ChorusUser::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; let token = chorus_request .deserialize_response::(&mut shell) .await? @@ -44,12 +44,12 @@ impl Instance { self.limits_information.as_mut().unwrap().ratelimits = shell.limits.unwrap(); } let user_object = self.get_user(token.clone(), None).await.unwrap(); - let settings = UserMeta::get_settings(&token, &self.urls.api.clone(), self).await?; + let settings = ChorusUser::get_settings(&token, &self.urls.api.clone(), self).await?; let mut identify = GatewayIdentifyPayload::common(); let gateway = Gateway::new(self.urls.wss.clone()).await.unwrap(); identify.token = token.clone(); gateway.send_identify(identify).await; - let user = UserMeta::new( + let user = ChorusUser::new( Rc::new(RefCell::new(self.clone())), token.clone(), self.clone_limits_if_some(), diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 518de59..6fd0d79 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -5,7 +5,7 @@ use crate::types::{AddChannelRecipientSchema, ModifyChannelPositionsSchema}; use crate::{ api::LimitType, errors::{ChorusError, ChorusResult}, - instance::UserMeta, + instance::ChorusUser, ratelimiter::ChorusRequest, types::{Channel, ChannelModifySchema, GetChannelMessagesSchema, Message, Snowflake}, }; @@ -15,7 +15,7 @@ impl Channel { /// /// # Reference /// See - pub async fn get(user: &mut UserMeta, channel_id: Snowflake) -> ChorusResult { + pub async fn get(user: &mut ChorusUser, channel_id: Snowflake) -> ChorusResult { let url = user.belongs_to.borrow().urls.api.clone(); let chorus_request = ChorusRequest { request: Client::new() @@ -33,7 +33,7 @@ impl Channel { /// /// # Reference /// See - pub async fn delete(self, user: &mut UserMeta) -> ChorusResult<()> { + pub async fn delete(self, user: &mut ChorusUser) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() .delete(format!( @@ -64,7 +64,7 @@ impl Channel { pub async fn modify( &self, modify_data: ChannelModifySchema, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let channel_id = self.id; let chorus_request = ChorusRequest { @@ -94,7 +94,7 @@ impl Channel { pub async fn messages( range: GetChannelMessagesSchema, channel_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> Result, ChorusError> { let chorus_request = ChorusRequest { request: Client::new() @@ -120,7 +120,7 @@ impl Channel { pub async fn add_channel_recipient( &self, recipient_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, add_channel_recipient_schema: Option, ) -> ChorusResult<()> { let mut request = Client::new() @@ -150,7 +150,7 @@ impl Channel { pub async fn remove_channel_recipient( &self, recipient_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let request = Client::new() .delete(format!( @@ -176,7 +176,7 @@ impl Channel { pub async fn modify_positions( schema: Vec, guild_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let request = Client::new() .patch(format!( diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 053ee75..2011c40 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -5,7 +5,7 @@ use serde_json::{from_value, to_string, Value}; use crate::api::LimitType; use crate::errors::{ChorusError, ChorusResult}; -use crate::instance::UserMeta; +use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ Channel, CreateGreetMessage, Message, MessageAck, MessageModifySchema, MessageSearchEndpoint, @@ -19,7 +19,7 @@ impl Message { /// # Reference /// See pub async fn send( - user: &mut UserMeta, + user: &mut ChorusUser, channel_id: Snowflake, mut message: MessageSendSchema, ) -> ChorusResult { @@ -87,7 +87,7 @@ impl Message { pub(crate) async fn search( endpoint: MessageSearchEndpoint, query: MessageSearchQuery, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult> { let limit_type = match &endpoint { MessageSearchEndpoint::Channel(id) => LimitType::Channel(*id), @@ -136,7 +136,7 @@ impl Message { /// See: pub async fn get_sticky( channel_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult> { let chorus_request = ChorusRequest { request: Client::new() @@ -162,7 +162,7 @@ impl Message { pub async fn sticky( channel_id: Snowflake, message_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() @@ -185,7 +185,7 @@ impl Message { pub async fn unsticky( channel_id: Snowflake, message_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() @@ -209,7 +209,7 @@ impl Message { pub async fn get( channel_id: Snowflake, message_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() @@ -232,7 +232,7 @@ impl Message { pub async fn create_greet( channel_id: Snowflake, schema: CreateGreetMessage, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() @@ -263,7 +263,7 @@ impl Message { channel_id: Snowflake, message_id: Snowflake, schema: MessageAck, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult> { let chorus_request = ChorusRequest { request: Client::new() @@ -292,7 +292,7 @@ impl Message { pub async fn crosspost( channel_id: Snowflake, message_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() @@ -316,7 +316,7 @@ impl Message { pub async fn hide_from_guild_feed( channel_id: Snowflake, message_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() @@ -347,7 +347,7 @@ impl Message { channel_id: Snowflake, message_id: Snowflake, schema: MessageModifySchema, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() @@ -370,7 +370,7 @@ impl Message { pub async fn delete( channel_id: Snowflake, message_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() @@ -399,7 +399,7 @@ impl Message { pub async fn bulk_delete( channel_id: Snowflake, messages: Vec, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { if messages.len() < 2 { return Err(ChorusError::InvalidArguments { @@ -427,7 +427,7 @@ impl Message { /// See: pub async fn acknowledge_pinned( channel_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let chorus_request = ChorusRequest { request: Client::new() @@ -453,7 +453,7 @@ fn search_error(result_text: String) -> ChorusError { } } -impl UserMeta { +impl ChorusUser { /// Sends a message in the channel with the provided channel_id. /// Returns the sent message. /// @@ -485,7 +485,7 @@ impl Channel { pub async fn search_messages( channel_id: Snowflake, query: MessageSearchQuery, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult> { Message::search(MessageSearchEndpoint::Channel(channel_id), query, user).await } diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 8a6316f..13da01d 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -4,7 +4,7 @@ use serde_json::to_string; use crate::{ api::LimitType, errors::{ChorusError, ChorusResult}, - instance::UserMeta, + instance::ChorusUser, ratelimiter::ChorusRequest, types::{self, PermissionOverwrite, Snowflake}, }; @@ -21,7 +21,7 @@ impl types::Channel { /// # Reference /// See pub async fn edit_permissions( - user: &mut UserMeta, + user: &mut ChorusUser, channel_id: Snowflake, overwrite: PermissionOverwrite, ) -> ChorusResult<()> { @@ -59,7 +59,7 @@ impl types::Channel { /// # Reference /// See pub async fn delete_permission( - user: &mut UserMeta, + user: &mut ChorusUser, channel_id: Snowflake, overwrite_id: Snowflake, ) -> ChorusResult<()> { diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index 519da12..f3b51a3 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -3,7 +3,7 @@ use reqwest::Client; use crate::{ api::LimitType, errors::ChorusResult, - instance::UserMeta, + instance::ChorusUser, ratelimiter::ChorusRequest, types::{self, PublicUser, Snowflake}, }; @@ -21,7 +21,7 @@ impl ReactionMeta { /// /// # Reference /// See - pub async fn delete_all(&self, user: &mut UserMeta) -> ChorusResult<()> { + pub async fn delete_all(&self, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions", user.belongs_to.borrow().urls.api, @@ -44,7 +44,7 @@ impl ReactionMeta { /// /// # Reference /// See - pub async fn get(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult> { + pub async fn get(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}", user.belongs_to.borrow().urls.api, @@ -70,7 +70,7 @@ impl ReactionMeta { /// /// # Reference /// See - pub async fn delete_emoji(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { + pub async fn delete_emoji(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}", user.belongs_to.borrow().urls.api, @@ -99,7 +99,7 @@ impl ReactionMeta { /// /// # Reference /// See - pub async fn create(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { + pub async fn create(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me", user.belongs_to.borrow().urls.api, @@ -124,7 +124,7 @@ impl ReactionMeta { /// /// # Reference /// See - pub async fn remove(&self, emoji: &str, user: &mut UserMeta) -> ChorusResult<()> { + pub async fn remove(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me", user.belongs_to.borrow().urls.api, @@ -154,7 +154,7 @@ impl ReactionMeta { &self, user_id: Snowflake, emoji: &str, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/{}", diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 85a18b7..a56b4c4 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -5,7 +5,7 @@ use serde_json::to_string; use crate::api::LimitType; use crate::errors::ChorusError; use crate::errors::ChorusResult; -use crate::instance::UserMeta; +use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildModifySchema, @@ -18,7 +18,7 @@ impl Guild { /// # Reference /// See pub async fn create( - user: &mut UserMeta, + user: &mut ChorusUser, guild_create_schema: GuildCreateSchema, ) -> ChorusResult { let url = format!("{}/guilds", user.belongs_to.borrow().urls.api); @@ -52,7 +52,7 @@ impl Guild { /// /// # Reference /// See - pub async fn delete(user: &mut UserMeta, guild_id: Snowflake) -> ChorusResult<()> { + pub async fn delete(user: &mut ChorusUser, guild_id: Snowflake) -> ChorusResult<()> { let url = format!( "{}/guilds/{}/delete", user.belongs_to.borrow().urls.api, @@ -79,7 +79,7 @@ impl Guild { /// See pub async fn create_channel( &self, - user: &mut UserMeta, + user: &mut ChorusUser, schema: ChannelCreateSchema, ) -> ChorusResult { Channel::create(user, self.id, schema).await @@ -91,7 +91,7 @@ impl Guild { /// /// # Reference /// See - pub async fn channels(&self, user: &mut UserMeta) -> ChorusResult> { + pub async fn channels(&self, user: &mut ChorusUser) -> ChorusResult> { let chorus_request = ChorusRequest { request: Client::new() .get(format!( @@ -125,7 +125,7 @@ impl Guild { /// /// # Reference /// See - pub async fn get(guild_id: Snowflake, user: &mut UserMeta) -> ChorusResult { + pub async fn get(guild_id: Snowflake, user: &mut ChorusUser) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() .get(format!( @@ -144,7 +144,7 @@ impl Guild { guild_id: Snowflake, user_id: Snowflake, schema: GuildBanCreateSchema, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() @@ -169,7 +169,7 @@ impl Guild { pub async fn modify( guild_id: Snowflake, schema: GuildModifySchema, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() @@ -195,7 +195,7 @@ impl Channel { /// # Reference /// See pub async fn create( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, schema: ChannelCreateSchema, ) -> ChorusResult { diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index f9f02dc..ca81ea1 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -3,7 +3,7 @@ use reqwest::Client; use crate::{ api::LimitType, errors::ChorusResult, - instance::UserMeta, + instance::ChorusUser, ratelimiter::ChorusRequest, types::{self, GuildMember, Snowflake}, }; @@ -14,7 +14,7 @@ impl types::GuildMember { /// # Reference /// See pub async fn get( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, member_id: Snowflake, ) -> ChorusResult { @@ -40,7 +40,7 @@ impl types::GuildMember { /// # Reference /// See pub async fn add_role( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, member_id: Snowflake, role_id: Snowflake, @@ -69,7 +69,7 @@ impl types::GuildMember { /// # Reference /// See pub async fn remove_role( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, member_id: Snowflake, role_id: Snowflake, diff --git a/src/api/guilds/messages.rs b/src/api/guilds/messages.rs index 72d886c..60fd4e3 100644 --- a/src/api/guilds/messages.rs +++ b/src/api/guilds/messages.rs @@ -1,5 +1,5 @@ use crate::errors::ChorusResult; -use crate::instance::UserMeta; +use crate::instance::ChorusUser; use crate::types::{Guild, Message, MessageSearchQuery, Snowflake}; impl Guild { @@ -16,7 +16,7 @@ impl Guild { pub async fn search_messages( guild_id: Snowflake, query: MessageSearchQuery, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult> { Message::search( crate::types::MessageSearchEndpoint::GuildChannel(guild_id), diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 678450c..eb837c9 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -4,7 +4,7 @@ use serde_json::to_string; use crate::{ api::LimitType, errors::{ChorusError, ChorusResult}, - instance::UserMeta, + instance::ChorusUser, ratelimiter::ChorusRequest, types::{self, RoleCreateModifySchema, RoleObject, RolePositionUpdateSchema, Snowflake}, }; @@ -15,7 +15,7 @@ impl types::RoleObject { /// # Reference /// See pub async fn get_all( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, ) -> ChorusResult> { let url = format!( @@ -39,7 +39,7 @@ impl types::RoleObject { /// # Reference /// See pub async fn get( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, role_id: Snowflake, ) -> ChorusResult { @@ -65,7 +65,7 @@ impl types::RoleObject { /// # Reference /// See pub async fn create( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, role_create_schema: RoleCreateModifySchema, ) -> ChorusResult { @@ -99,7 +99,7 @@ impl types::RoleObject { /// # Reference /// See pub async fn position_update( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, role_position_update_schema: RolePositionUpdateSchema, ) -> ChorusResult { @@ -132,7 +132,7 @@ impl types::RoleObject { /// # Reference /// See pub async fn modify( - user: &mut UserMeta, + user: &mut ChorusUser, guild_id: Snowflake, role_id: Snowflake, role_create_schema: RoleCreateModifySchema, diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index 8742c3f..88a5705 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -2,11 +2,11 @@ use reqwest::Client; use serde_json::to_string; use crate::errors::ChorusResult; -use crate::instance::UserMeta; +use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{CreateChannelInviteSchema, GuildInvite, Invite, Snowflake}; -impl UserMeta { +impl ChorusUser { /// Accepts an invite to a guild, group DM, or DM. /// /// Note that the session ID is required for guest invites. diff --git a/src/api/users/channels.rs b/src/api/users/channels.rs index 5a33c6c..993894f 100644 --- a/src/api/users/channels.rs +++ b/src/api/users/channels.rs @@ -4,12 +4,12 @@ use serde_json::to_string; use crate::{ api::LimitType, errors::ChorusResult, - instance::UserMeta, + instance::ChorusUser, ratelimiter::ChorusRequest, types::{Channel, PrivateChannelCreateSchema}, }; -impl UserMeta { +impl ChorusUser { /// Creates a DM channel or group DM channel. /// /// One recipient creates or returns an existing DM channel, diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index 355f38c..7e0a6c2 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -2,11 +2,11 @@ use reqwest::Client; use serde_json::to_string; use crate::errors::ChorusResult; -use crate::instance::UserMeta; +use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::Snowflake; -impl UserMeta { +impl ChorusUser { /// Leaves a given guild. /// /// # Reference: diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index e08f414..ae4ee27 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -4,14 +4,14 @@ use serde_json::to_string; use crate::{ api::LimitType, errors::ChorusResult, - instance::UserMeta, + instance::ChorusUser, ratelimiter::ChorusRequest, types::{ self, CreateUserRelationshipSchema, FriendRequestSendSchema, RelationshipType, Snowflake, }, }; -impl UserMeta { +impl ChorusUser { /// Retrieves a list of mutual friends between the authenticated user and a given user. /// /// # Reference diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 41af054..d80700e 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -6,12 +6,12 @@ use serde_json::to_string; use crate::{ api::LimitType, errors::{ChorusError, ChorusResult}, - instance::{Instance, UserMeta}, + instance::{ChorusUser, Instance}, ratelimiter::ChorusRequest, types::{User, UserModifySchema, UserSettings}, }; -impl UserMeta { +impl ChorusUser { /// Gets a user by id, or if the id is None, gets the current user. /// /// # Notes @@ -85,7 +85,7 @@ impl User { /// # Reference /// See and /// - pub async fn get(user: &mut UserMeta, id: Option<&String>) -> ChorusResult { + pub async fn get(user: &mut ChorusUser, id: Option<&String>) -> ChorusResult { let url_api = user.belongs_to.borrow().urls.api.clone(); let url = if id.is_none() { format!("{}/users/@me", url_api) @@ -121,7 +121,7 @@ impl User { .get(format!("{}/users/@me/settings", url_api)) .header("Authorization", token); let mut user = - UserMeta::shell(Rc::new(RefCell::new(instance.clone())), token.clone()).await; + ChorusUser::shell(Rc::new(RefCell::new(instance.clone())), token.clone()).await; let chorus_request = ChorusRequest { request, limit_type: LimitType::Global, @@ -148,7 +148,7 @@ impl Instance { /// See and /// pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult { - let mut user = UserMeta::shell(Rc::new(RefCell::new(self.clone())), token).await; + let mut user = ChorusUser::shell(Rc::new(RefCell::new(self.clone())), token).await; let result = User::get(&mut user, id).await; if self.limits_information.is_some() { self.limits_information.as_mut().unwrap().ratelimits = diff --git a/src/instance.rs b/src/instance.rs index 4ed0f60..ba67abc 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -87,7 +87,7 @@ impl fmt::Display for Token { /// A UserMeta is a representation of an authenticated user on an [Instance]. /// It is used for most authenticated actions on a Spacebar server. /// It also has its own [Gateway] connection. -pub struct UserMeta { +pub struct ChorusUser { pub belongs_to: Rc>, pub token: String, pub limits: Option>, @@ -96,7 +96,7 @@ pub struct UserMeta { pub gateway: GatewayHandle, } -impl UserMeta { +impl ChorusUser { pub fn token(&self) -> String { self.token.clone() } @@ -117,8 +117,8 @@ impl UserMeta { settings: Arc>, object: Arc>, gateway: GatewayHandle, - ) -> UserMeta { - UserMeta { + ) -> ChorusUser { + ChorusUser { belongs_to, token, limits, @@ -133,13 +133,13 @@ impl UserMeta { /// registering or logging in to the Instance, where you do not yet have a User object, but still /// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify /// first. - pub(crate) async fn shell(instance: Rc>, token: String) -> UserMeta { + pub(crate) async fn shell(instance: Rc>, token: String) -> ChorusUser { let settings = Arc::new(RwLock::new(UserSettings::default())); let object = Arc::new(RwLock::new(User::default())); let wss_url = instance.borrow().urls.wss.clone(); // Dummy gateway object let gateway = Gateway::new(wss_url).await.unwrap(); - UserMeta { + ChorusUser { token, belongs_to: instance.clone(), limits: instance diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 2c1ecd0..7e9d7fc 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -8,7 +8,7 @@ use serde_json::from_str; use crate::{ api::{Limit, LimitType}, errors::{ChorusError, ChorusResult}, - instance::UserMeta, + instance::ChorusUser, types::{types::subconfigs::limits::rates::RateLimits, LimitsConfiguration}, }; @@ -24,7 +24,7 @@ impl ChorusRequest { /// If the user is not rate limited and the instance has rate limits enabled, it will update the /// rate limits. #[allow(clippy::await_holding_refcell_ref)] - pub(crate) async fn send_request(self, user: &mut UserMeta) -> ChorusResult { + pub(crate) async fn send_request(self, user: &mut ChorusUser) -> ChorusResult { if !ChorusRequest::can_send_request(user, &self.limit_type) { log::info!("Rate limit hit. Bucket: {:?}", self.limit_type); return Err(ChorusError::RateLimited { @@ -73,7 +73,7 @@ impl ChorusRequest { Ok(result) } - fn can_send_request(user: &mut UserMeta, limit_type: &LimitType) -> bool { + fn can_send_request(user: &mut ChorusUser, limit_type: &LimitType) -> bool { log::trace!("Checking if user or instance is rate-limited..."); let mut belongs_to = user.belongs_to.borrow_mut(); if belongs_to.limits_information.is_none() { @@ -236,7 +236,7 @@ impl ChorusRequest { /// set to the current unix timestamp + the rate limit window. The remaining rate limit is /// reset to the rate limit limit. /// 2. The remaining rate limit is decreased by 1. - fn update_rate_limits(user: &mut UserMeta, limit_type: &LimitType, response_was_err: bool) { + fn update_rate_limits(user: &mut ChorusUser, limit_type: &LimitType, response_was_err: bool) { if user.belongs_to.borrow().limits_information.is_none() { return; } @@ -429,7 +429,7 @@ impl ChorusRequest { /// Sends a [`ChorusRequest`] and returns a [`ChorusResult`] that contains nothing if the request /// was successful, or a [`ChorusError`] if the request failed. - pub(crate) async fn handle_request_as_result(self, user: &mut UserMeta) -> ChorusResult<()> { + pub(crate) async fn handle_request_as_result(self, user: &mut ChorusUser) -> ChorusResult<()> { match self.send_request(user).await { Ok(_) => Ok(()), Err(e) => Err(e), @@ -440,7 +440,7 @@ impl ChorusRequest { /// was successful, or a [`ChorusError`] if the request failed. pub(crate) async fn deserialize_response Deserialize<'a>>( self, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let response = self.send_request(user).await?; debug!("Got response: {:?}", response); diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 2dc0718..b1f9639 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -2,7 +2,7 @@ use std::sync::{Arc, RwLock}; use chorus::gateway::Gateway; use chorus::{ - instance::{Instance, UserMeta}, + instance::{ChorusUser, Instance}, types::{ Channel, ChannelCreateSchema, Guild, GuildCreateSchema, RegisterSchema, RoleCreateModifySchema, RoleObject, @@ -14,7 +14,7 @@ use chorus::{ #[derive(Debug)] pub(crate) struct TestBundle { pub urls: UrlBundle, - pub user: UserMeta, + pub user: ChorusUser, pub instance: Instance, pub guild: Arc>, pub role: Arc>, @@ -23,7 +23,7 @@ pub(crate) struct TestBundle { #[allow(unused)] impl TestBundle { - pub(crate) async fn create_user(&mut self, username: &str) -> UserMeta { + pub(crate) async fn create_user(&mut self, username: &str) -> ChorusUser { let register_schema = RegisterSchema { username: username.to_string(), consent: true, @@ -35,8 +35,8 @@ impl TestBundle { .await .unwrap() } - pub(crate) async fn clone_user_without_gateway(&self) -> UserMeta { - UserMeta { + pub(crate) async fn clone_user_without_gateway(&self) -> ChorusUser { + ChorusUser { belongs_to: self.user.belongs_to.clone(), token: self.user.token.clone(), limits: self.user.limits.clone(), From 64ba6a657a03facc9a52f73554b2dae374aa4bd2 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 24 Aug 2023 21:09:23 +0200 Subject: [PATCH 153/237] Change `UserMeta` to `ChorusUser` --- src/instance.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index ba67abc..7219c03 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -84,7 +84,7 @@ impl fmt::Display for Token { } #[derive(Debug)] -/// A UserMeta is a representation of an authenticated user on an [Instance]. +/// A ChorusUser is a representation of an authenticated user on an [Instance]. /// It is used for most authenticated actions on a Spacebar server. /// It also has its own [Gateway] connection. pub struct ChorusUser { @@ -105,10 +105,10 @@ impl ChorusUser { self.token = token; } - /// Creates a new [UserMeta] from existing data. + /// Creates a new [ChorusUser] from existing data. /// /// # Notes - /// This isn't the prefered way to create a UserMeta. + /// This isn't the prefered way to create a ChorusUser. /// See [Instance::login_account] and [Instance::register_account] instead. pub fn new( belongs_to: Rc>, @@ -129,7 +129,7 @@ impl ChorusUser { } /// Creates a new 'shell' of a user. The user does not exist as an object, and exists so that you have - /// a UserMeta object to make Rate Limited requests with. This is useful in scenarios like + /// a ChorusUser object to make Rate Limited requests with. This is useful in scenarios like /// registering or logging in to the Instance, where you do not yet have a User object, but still /// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify /// first. From eb163d278a4e903e2e365f29b4bd30aed0c47aab Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 24 Aug 2023 21:46:02 +0200 Subject: [PATCH 154/237] Change UserMeta to ChorusUser --- src/api/guilds/guilds.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 48bbf7a..370922a 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -194,7 +194,7 @@ impl Guild { /// See pub async fn get_preview( guild_id: Snowflake, - user: &mut UserMeta, + user: &mut ChorusUser, ) -> ChorusResult { let chorus_request = ChorusRequest { request: Client::new() From 87d325e38f5574ec2ded8435fd6fb4ae6e912015 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 24 Aug 2023 22:29:26 +0200 Subject: [PATCH 155/237] Create ChorusRequest-builder function --- src/ratelimiter.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 7e9d7fc..3e9ad48 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; use log::{self, debug}; use reqwest::{Client, RequestBuilder, Response}; -use serde::Deserialize; -use serde_json::from_str; +use serde::{Deserialize, Serialize}; +use serde_json::{from_str, to_string}; use crate::{ api::{Limit, LimitType}, @@ -20,6 +20,53 @@ pub struct ChorusRequest { } impl ChorusRequest { + /// Makes a new [`ChorusRequest`]. + /// # Arguments + /// * `method` - The HTTP method to use. Must be one of the following: + /// * [`http::Method::GET`] + /// * [`http::Method::POST`] + /// * [`http::Method::PUT`] + /// * [`http::Method::DELETE`] + /// * [`http::Method::PATCH`] + /// * [`http::Method::HEAD`] + pub(crate) fn new( + method: http::Method, + url: &str, + body: Option, + audit_log_reason: Option<&str>, + mfa_token: Option<&str>, + chorus_user: Option<&mut ChorusUser>, + limit_type: LimitType, + ) -> ChorusRequest { + let mut request = Client::new(); + let request = match method { + http::Method::GET => request.get(url), + http::Method::POST => request.post(url), + http::Method::PUT => request.put(url), + http::Method::DELETE => request.delete(url), + http::Method::PATCH => request.patch(url), + http::Method::HEAD => request.head(url), + _ => panic!("Illegal state: Method not supported."), + }; + if let Some(user) = chorus_user { + let request = request.header("Authorization", user.token()); + } + if let Some(body) = body { + // ONCE TOLD ME THE WORLD WAS GONNA ROLL ME + let request = request + .body(to_string(&body).unwrap()) + .header("Content-Type", "application/json"); + } + if let Some(reason) = audit_log_reason { + let request = request.header("X-Audit-Log-Reason", reason); + } + + ChorusRequest { + request, + limit_type, + } + } + /// Sends a [`ChorusRequest`]. Checks if the user is rate limited, and if not, sends the request. /// If the user is not rate limited and the instance has rate limits enabled, it will update the /// rate limits. From e9318ea4dca617ced1664cc92a1b712da8371686 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Thu, 24 Aug 2023 22:30:13 +0200 Subject: [PATCH 156/237] start adding auditlogreason to routes that take it --- src/api/channels/channels.rs | 47 +++++++++++------ src/api/channels/messages.rs | 92 ++++++++++++++++++++------------- src/api/channels/permissions.rs | 17 +++--- src/api/guilds/guilds.rs | 23 +++++---- 4 files changed, 111 insertions(+), 68 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 6fd0d79..1bb7538 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -33,15 +33,23 @@ impl Channel { /// /// # Reference /// See - pub async fn delete(self, user: &mut ChorusUser) -> ChorusResult<()> { + pub async fn delete( + self, + audit_log_reason: Option, + user: &mut ChorusUser, + ) -> ChorusResult<()> { + let mut request = Client::new() + .delete(format!( + "{}/channels/{}", + user.belongs_to.borrow().urls.api, + self.id + )) + .header("Authorization", user.token()); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .delete(format!( - "{}/channels/{}", - user.belongs_to.borrow().urls.api, - self.id - )) - .header("Authorization", user.token()), + request, limit_type: LimitType::Channel(self.id), }; chorus_request.handle_request_as_result(user).await @@ -64,19 +72,24 @@ impl Channel { pub async fn modify( &self, modify_data: ChannelModifySchema, + audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult { let channel_id = self.id; + let mut request = Client::new() + .patch(format!( + "{}/channels/{}", + user.belongs_to.borrow().urls.api, + channel_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(to_string(&modify_data).unwrap()); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .patch(format!( - "{}/channels/{}", - user.belongs_to.borrow().urls.api, - channel_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&modify_data).unwrap()), + request, limit_type: LimitType::Channel(channel_id), }; chorus_request.deserialize_response::(user).await diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 2011c40..6f6c2be 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -162,18 +162,23 @@ impl Message { pub async fn sticky( channel_id: Snowflake, message_id: Snowflake, + audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult<()> { + let mut request = Client::new() + .put(format!( + "{}/channels/{}/pins/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .put(format!( - "{}/channels/{}/pins/{}", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), + request, limit_type: LimitType::Channel(channel_id), }; chorus_request.handle_request_as_result(user).await @@ -185,18 +190,23 @@ impl Message { pub async fn unsticky( channel_id: Snowflake, message_id: Snowflake, + audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult<()> { + let mut request = Client::new() + .delete(format!( + "{}/channels/{}/pins/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .delete(format!( - "{}/channels/{}/pins/{}", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), + request, limit_type: LimitType::Channel(channel_id), }; chorus_request.handle_request_as_result(user).await @@ -370,18 +380,23 @@ impl Message { pub async fn delete( channel_id: Snowflake, message_id: Snowflake, + audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult<()> { + let mut request = Client::new() + .delete(format!( + "{}/channels/{}/messages/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json"); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .delete(format!( - "{}/channels/{}/messages/{}", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), + request, limit_type: LimitType::Channel(channel_id), }; chorus_request.handle_request_as_result(user).await @@ -399,6 +414,7 @@ impl Message { pub async fn bulk_delete( channel_id: Snowflake, messages: Vec, + audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult<()> { if messages.len() < 2 { @@ -406,16 +422,20 @@ impl Message { error: "`messages` must contain at least 2 entries.".to_string(), }); } + let mut request = Client::new() + .post(format!( + "{}/channels/{}/messages/bulk-delete", + user.belongs_to.borrow().urls.api, + channel_id, + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(to_string(&messages).unwrap()); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .post(format!( - "{}/channels/{}/messages/bulk-delete", - user.belongs_to.borrow().urls.api, - channel_id, - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&messages).unwrap()), + request, limit_type: LimitType::Channel(channel_id), }; chorus_request.handle_request_as_result(user).await diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 13da01d..9a4c01d 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -20,9 +20,10 @@ impl types::Channel { /// /// # Reference /// See - pub async fn edit_permissions( + pub async fn modify_permissions( user: &mut ChorusUser, channel_id: Snowflake, + audit_log_reason: Option, overwrite: PermissionOverwrite, ) -> ChorusResult<()> { let url = format!( @@ -39,12 +40,16 @@ impl types::Channel { }); } }; + let mut request = Client::new() + .put(url) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(body); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .put(url) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(body), + request, limit_type: LimitType::Channel(channel_id), }; chorus_request.handle_request_as_result(user).await diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index a56b4c4..ec33721 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -198,17 +198,22 @@ impl Channel { user: &mut ChorusUser, guild_id: Snowflake, schema: ChannelCreateSchema, + audit_log_reason: Option, ) -> ChorusResult { + let mut request = Client::new() + .post(format!( + "{}/guilds/{}/channels", + user.belongs_to.borrow().urls.api, + guild_id + )) + .header("Authorization", user.token()) + .header("Content-Type", "application/json") + .body(to_string(&schema).unwrap()); + if let Some(reason) = audit_log_reason { + request = request.header("X-Audit-Log-Reason", reason); + } let chorus_request = ChorusRequest { - request: Client::new() - .post(format!( - "{}/guilds/{}/channels", - user.belongs_to.borrow().urls.api, - guild_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&schema).unwrap()), + request, limit_type: LimitType::Guild(guild_id), }; chorus_request.deserialize_response::(user).await From d73c1963fc1784e9af2d6d9c3aab90b47cc5053a Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 00:02:26 +0200 Subject: [PATCH 157/237] Start refactoring ChorusRequest to ChorusRequest::new() --- src/api/channels/channels.rs | 173 ++++++++++-------- src/api/channels/messages.rs | 308 +++++++++++++++++--------------- src/api/channels/permissions.rs | 19 +- src/api/channels/reactions.rs | 117 +++++++----- src/api/guilds/guilds.rs | 5 +- src/ratelimiter.rs | 21 +-- tests/channels.rs | 18 +- tests/common/mod.rs | 2 +- tests/gateway.rs | 2 +- tests/messages.rs | 4 +- 10 files changed, 371 insertions(+), 298 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 1bb7538..9565877 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -16,13 +16,20 @@ impl Channel { /// # Reference /// See pub async fn get(user: &mut ChorusUser, channel_id: Snowflake) -> ChorusResult { - let url = user.belongs_to.borrow().urls.api.clone(); - let chorus_request = ChorusRequest { - request: Client::new() - .get(format!("{}/channels/{}", url, channel_id)) - .header("Authorization", user.token()), - limit_type: LimitType::Channel(channel_id), - }; + let chorus_request = ChorusRequest::new( + http::Method::GET, + &format!( + "{}/channels/{}", + user.belongs_to.borrow().urls.api.clone(), + channel_id + ), + None, + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); + chorus_request.deserialize_response::(user).await } @@ -38,21 +45,19 @@ impl Channel { audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult<()> { - let mut request = Client::new() - .delete(format!( - "{}/channels/{}", - user.belongs_to.borrow().urls.api, - self.id - )) - .header("Authorization", user.token()); - if let Some(reason) = audit_log_reason { - request = request.header("X-Audit-Log-Reason", reason); - } - let chorus_request = ChorusRequest { - request, - limit_type: LimitType::Channel(self.id), - }; - chorus_request.handle_request_as_result(user).await + let url = format!("{}/channels/{}", user.belongs_to.borrow().urls.api, self.id,); + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Channel(self.id), + ); + + request.handle_request_as_result(user).await } /// Modifies a channel with the provided data. @@ -76,23 +81,23 @@ impl Channel { user: &mut ChorusUser, ) -> ChorusResult { let channel_id = self.id; - let mut request = Client::new() - .patch(format!( - "{}/channels/{}", - user.belongs_to.borrow().urls.api, - channel_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&modify_data).unwrap()); - if let Some(reason) = audit_log_reason { - request = request.header("X-Audit-Log-Reason", reason); - } - let chorus_request = ChorusRequest { - request, - limit_type: LimitType::Channel(channel_id), - }; - chorus_request.deserialize_response::(user).await + let url = format!( + "{}/channels/{}", + user.belongs_to.borrow().urls.api, + channel_id + ); + + let request = ChorusRequest::new( + http::Method::PATCH, + &url, + Some(to_string(&modify_data).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Channel(channel_id), + ); + + request.deserialize_response::(user).await } /// Fetches recent messages from a channel. @@ -109,17 +114,22 @@ impl Channel { channel_id: Snowflake, user: &mut ChorusUser, ) -> Result, ChorusError> { - let chorus_request = ChorusRequest { - request: Client::new() - .get(format!( - "{}/channels/{}/messages", - user.belongs_to.borrow().urls.api, - channel_id - )) - .header("Authorization", user.token()) - .query(&range), - limit_type: Default::default(), - }; + let url = format!( + "{}/channels/{}/messages", + user.belongs_to.borrow().urls.api, + channel_id + ); + + let mut chorus_request = ChorusRequest::new( + http::Method::GET, + &url, + None, + None, + None, + Some(user), + Default::default(), + ); + chorus_request.request = chorus_request.request.query(&range); chorus_request .deserialize_response::>(user) @@ -165,20 +175,24 @@ impl Channel { recipient_id: Snowflake, user: &mut ChorusUser, ) -> ChorusResult<()> { - let request = Client::new() - .delete(format!( - "{}/channels/{}/recipients/{}", - user.belongs_to.borrow().urls.api, - self.id, - recipient_id - )) - .header("Authorization", user.token()); - ChorusRequest { - request, - limit_type: LimitType::Channel(self.id), - } - .handle_request_as_result(user) - .await + let url = format!( + "{}/channels/{}/recipients/{}", + user.belongs_to.borrow().urls.api, + self.id, + recipient_id + ); + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(self.id), + ); + + request.handle_request_as_result(user).await } /// Modifies the positions of a set of channel objects for the guild. Requires the `MANAGE_CHANNELS` permission. @@ -191,19 +205,22 @@ impl Channel { guild_id: Snowflake, user: &mut ChorusUser, ) -> ChorusResult<()> { - let request = Client::new() - .patch(format!( - "{}/guilds/{}/channels", - user.belongs_to.borrow().urls.api, - guild_id - )) - .header("Authorization", user.token()) - .body(to_string(&schema).unwrap()); - ChorusRequest { - request, - limit_type: LimitType::Guild(guild_id), - } - .handle_request_as_result(user) - .await + let url = format!( + "{}/guilds/{}/channels", + user.belongs_to.borrow().urls.api, + guild_id + ); + + let request = ChorusRequest::new( + http::Method::PATCH, + &url, + Some(to_string(&schema).unwrap()), + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + + request.handle_request_as_result(user).await } } diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 6f6c2be..dc79f82 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -138,17 +138,20 @@ impl Message { channel_id: Snowflake, user: &mut ChorusUser, ) -> ChorusResult> { - let chorus_request = ChorusRequest { - request: Client::new() - .get(format!( - "{}/channels/{}/pins", - user.belongs_to.borrow().urls.api, - channel_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), - limit_type: LimitType::Channel(channel_id), - }; + let chorus_request = ChorusRequest::new( + http::Method::GET, + format!( + "{}/channels/{}/pins", + user.belongs_to.borrow().urls.api, + channel_id + ) + .as_str(), + None, + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); chorus_request .deserialize_response::>(user) .await @@ -162,26 +165,25 @@ impl Message { pub async fn sticky( channel_id: Snowflake, message_id: Snowflake, - audit_log_reason: Option, + audit_log_reason: Option<&str>, user: &mut ChorusUser, ) -> ChorusResult<()> { - let mut request = Client::new() - .put(format!( + let request = ChorusRequest::new( + http::Method::PUT, + format!( "{}/channels/{}/pins/{}", user.belongs_to.borrow().urls.api, channel_id, message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"); - if let Some(reason) = audit_log_reason { - request = request.header("X-Audit-Log-Reason", reason); - } - let chorus_request = ChorusRequest { - request, - limit_type: LimitType::Channel(channel_id), - }; - chorus_request.handle_request_as_result(user).await + ) + .as_str(), + None, + audit_log_reason, + None, + Some(user), + LimitType::Channel(channel_id), + ); + request.handle_request_as_result(user).await } /// Unpins a message in a channel. Requires the `MANAGE_MESSAGES` permission. Returns a 204 empty response on success. @@ -190,26 +192,25 @@ impl Message { pub async fn unsticky( channel_id: Snowflake, message_id: Snowflake, - audit_log_reason: Option, + audit_log_reason: Option<&str>, user: &mut ChorusUser, ) -> ChorusResult<()> { - let mut request = Client::new() - .delete(format!( + let request = ChorusRequest::new( + http::Method::DELETE, + format!( "{}/channels/{}/pins/{}", user.belongs_to.borrow().urls.api, channel_id, message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"); - if let Some(reason) = audit_log_reason { - request = request.header("X-Audit-Log-Reason", reason); - } - let chorus_request = ChorusRequest { - request, - limit_type: LimitType::Channel(channel_id), - }; - chorus_request.handle_request_as_result(user).await + ) + .as_str(), + None, + audit_log_reason, + None, + Some(user), + LimitType::Channel(channel_id), + ); + request.handle_request_as_result(user).await } /// Returns a specific message object in the channel. @@ -244,19 +245,21 @@ impl Message { schema: CreateGreetMessage, user: &mut ChorusUser, ) -> ChorusResult { - let chorus_request = ChorusRequest { - request: Client::new() - .post(format!( - "{}/channels/{}/messages/greet", - user.belongs_to.borrow().urls.api, - channel_id, - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&schema).unwrap()), - limit_type: LimitType::Channel(channel_id), - }; - chorus_request.deserialize_response::(user).await + let request = ChorusRequest::new( + http::Method::POST, + format!( + "{}/channels/{}/messages/greet", + user.belongs_to.borrow().urls.api, + channel_id, + ) + .as_str(), + Some(to_string(&schema).unwrap()), + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); + request.deserialize_response::(user).await } /// Sets the channel's latest acknowledged message (marks a message as read) for the current user. @@ -275,22 +278,22 @@ impl Message { schema: MessageAck, user: &mut ChorusUser, ) -> ChorusResult> { - let chorus_request = ChorusRequest { - request: Client::new() - .post(format!( - "{}/channels/{}/messages/{}/ack", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&schema).unwrap()), - limit_type: LimitType::Channel(channel_id), - }; - chorus_request - .deserialize_response::>(user) - .await + let request = ChorusRequest::new( + http::Method::POST, + format!( + "{}/channels/{}/messages/{}/ack", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + ) + .as_str(), + Some(to_string(&schema).unwrap()), + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); + request.deserialize_response::>(user).await } /// Crossposts a message in a News Channel to following channels. @@ -304,19 +307,22 @@ impl Message { message_id: Snowflake, user: &mut ChorusUser, ) -> ChorusResult { - let chorus_request = ChorusRequest { - request: Client::new() - .post(format!( - "{}/channels/{}/messages/{}/crosspost", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), - limit_type: LimitType::Channel(channel_id), - }; - chorus_request.deserialize_response::(user).await + let request = ChorusRequest::new( + http::Method::POST, + format!( + "{}/channels/{}/messages/{}/crosspost", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + ) + .as_str(), + None, + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); + request.deserialize_response::(user).await } /// Hides a message from the feed of the guild the channel belongs to. Returns a 204 empty response on success. @@ -328,18 +334,21 @@ impl Message { message_id: Snowflake, user: &mut ChorusUser, ) -> ChorusResult<()> { - let chorus_request = ChorusRequest { - request: Client::new() - .delete(format!( - "{}/channels/{}/messages/{}/hide-guild-feed", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), - limit_type: LimitType::Channel(channel_id), - }; + let url = format!( + "{}/channels/{}/messages/{}/hide-guild-feed", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + ); + let chorus_request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); chorus_request.handle_request_as_result(user).await } @@ -359,19 +368,21 @@ impl Message { schema: MessageModifySchema, user: &mut ChorusUser, ) -> ChorusResult { - let chorus_request = ChorusRequest { - request: Client::new() - .patch(format!( - "{}/channels/{}/messages/{}", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&schema).unwrap()), - limit_type: LimitType::Channel(channel_id), - }; + let url = format!( + "{}/channels/{}/messages/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + ); + let chorus_request = ChorusRequest::new( + http::Method::PATCH, + &url, + Some(to_string(&schema).unwrap()), + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); chorus_request.deserialize_response::(user).await } @@ -383,22 +394,23 @@ impl Message { audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult<()> { - let mut request = Client::new() - .delete(format!( - "{}/channels/{}/messages/{}", - user.belongs_to.borrow().urls.api, - channel_id, - message_id - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"); - if let Some(reason) = audit_log_reason { - request = request.header("X-Audit-Log-Reason", reason); - } - let chorus_request = ChorusRequest { - request, - limit_type: LimitType::Channel(channel_id), - }; + let url = format!( + "{}/channels/{}/messages/{}", + user.belongs_to.borrow().urls.api, + channel_id, + message_id + ); + + let chorus_request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Channel(channel_id), + ); + chorus_request.handle_request_as_result(user).await } @@ -422,23 +434,21 @@ impl Message { error: "`messages` must contain at least 2 entries.".to_string(), }); } - let mut request = Client::new() - .post(format!( + let request = ChorusRequest::new( + http::Method::POST, + format!( "{}/channels/{}/messages/bulk-delete", user.belongs_to.borrow().urls.api, channel_id, - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json") - .body(to_string(&messages).unwrap()); - if let Some(reason) = audit_log_reason { - request = request.header("X-Audit-Log-Reason", reason); - } - let chorus_request = ChorusRequest { - request, - limit_type: LimitType::Channel(channel_id), - }; - chorus_request.handle_request_as_result(user).await + ) + .as_str(), + Some(to_string(&messages).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Channel(channel_id), + ); + request.handle_request_as_result(user).await } /// Acknowledges the currently pinned messages in a channel. Returns a 204 empty response on success. @@ -449,17 +459,21 @@ impl Message { channel_id: Snowflake, user: &mut ChorusUser, ) -> ChorusResult<()> { - let chorus_request = ChorusRequest { - request: Client::new() - .post(format!( - "{}/channels/{}/pins/ack", - user.belongs_to.borrow().urls.api, - channel_id, - )) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), - limit_type: LimitType::Channel(channel_id), - }; + let chorus_request = ChorusRequest::new( + http::Method::POST, + format!( + "{}/channels/{}/pins/ack", + user.belongs_to.borrow().urls.api, + channel_id, + ) + .as_str(), + None, + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); + chorus_request.handle_request_as_result(user).await } } diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 9a4c01d..b932e11 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -74,12 +74,17 @@ impl types::Channel { channel_id, overwrite_id ); - let chorus_request = ChorusRequest { - request: Client::new() - .delete(url) - .header("Authorization", user.token()), - limit_type: LimitType::Channel(channel_id), - }; - chorus_request.handle_request_as_result(user).await + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(channel_id), + ); + + request.handle_request_as_result(user).await } } diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index f3b51a3..d44a61c 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -1,5 +1,3 @@ -use reqwest::Client; - use crate::{ api::LimitType, errors::ChorusResult, @@ -28,13 +26,18 @@ impl ReactionMeta { self.channel_id, self.message_id ); - let chorus_request = ChorusRequest { - request: Client::new() - .delete(url) - .header("Authorization", user.token()), - limit_type: LimitType::Channel(self.channel_id), - }; - chorus_request.handle_request_as_result(user).await + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(self.channel_id), + ); + + request.handle_request_as_result(user).await } /// Gets a list of users that reacted with a specific emoji to a message. @@ -52,13 +55,18 @@ impl ReactionMeta { self.message_id, emoji ); - let chorus_request = ChorusRequest { - request: Client::new().get(url).header("Authorization", user.token()), - limit_type: LimitType::Channel(self.channel_id), - }; - chorus_request - .deserialize_response::>(user) - .await + + let request = ChorusRequest::new( + http::Method::GET, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(self.channel_id), + ); + + request.deserialize_response::>(user).await } /// Deletes all the reactions for a given emoji on a message. @@ -78,13 +86,18 @@ impl ReactionMeta { self.message_id, emoji ); - let chorus_request = ChorusRequest { - request: Client::new() - .delete(url) - .header("Authorization", user.token()), - limit_type: LimitType::Channel(self.channel_id), - }; - chorus_request.handle_request_as_result(user).await + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(self.channel_id), + ); + + request.handle_request_as_result(user).await } /// Create a reaction on a message. @@ -107,14 +120,18 @@ impl ReactionMeta { self.message_id, emoji ); - let chorus_request = ChorusRequest { - request: Client::new() - .put(url) - .header("Authorization", user.token()) - .header("Content-Type", "application/json"), - limit_type: LimitType::Channel(self.channel_id), - }; - chorus_request.handle_request_as_result(user).await + + let request = ChorusRequest::new( + http::Method::PUT, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(self.channel_id), + ); + + request.handle_request_as_result(user).await } /// Deletes a reaction the current user has made to the message. @@ -132,13 +149,18 @@ impl ReactionMeta { self.message_id, emoji ); - let chorus_request = ChorusRequest { - request: Client::new() - .delete(url) - .header("Authorization", user.token()), - limit_type: LimitType::Channel(self.channel_id), - }; - chorus_request.handle_request_as_result(user).await + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(self.channel_id), + ); + + request.handle_request_as_result(user).await } /// Deletes a user's reaction to a message. @@ -164,12 +186,17 @@ impl ReactionMeta { emoji, user_id ); - let chorus_request = ChorusRequest { - request: Client::new() - .delete(url) - .header("Authorization", user.token()), - limit_type: LimitType::Channel(self.channel_id), - }; - chorus_request.handle_request_as_result(user).await + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + None, + None, + Some(user), + LimitType::Channel(self.channel_id), + ); + + request.handle_request_as_result(user).await } } diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index ec33721..78e32c4 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -80,9 +80,10 @@ impl Guild { pub async fn create_channel( &self, user: &mut ChorusUser, + audit_log_reason: Option, schema: ChannelCreateSchema, ) -> ChorusResult { - Channel::create(user, self.id, schema).await + Channel::create(user, self.id, audit_log_reason, schema).await } /// Returns a list of the guild's channels. @@ -197,8 +198,8 @@ impl Channel { pub async fn create( user: &mut ChorusUser, guild_id: Snowflake, - schema: ChannelCreateSchema, audit_log_reason: Option, + schema: ChannelCreateSchema, ) -> ChorusResult { let mut request = Client::new() .post(format!( diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 3e9ad48..766e68a 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; use log::{self, debug}; use reqwest::{Client, RequestBuilder, Response}; -use serde::{Deserialize, Serialize}; -use serde_json::{from_str, to_string}; +use serde::Deserialize; +use serde_json::from_str; use crate::{ api::{Limit, LimitType}, @@ -29,17 +29,18 @@ impl ChorusRequest { /// * [`http::Method::DELETE`] /// * [`http::Method::PATCH`] /// * [`http::Method::HEAD`] - pub(crate) fn new( + #[allow(unused_variables)] // TODO: Add mfa_token to request, once we figure out *how* to do so correctly + pub fn new( method: http::Method, url: &str, - body: Option, + body: Option, audit_log_reason: Option<&str>, mfa_token: Option<&str>, chorus_user: Option<&mut ChorusUser>, limit_type: LimitType, ) -> ChorusRequest { - let mut request = Client::new(); - let request = match method { + let request = Client::new(); + let mut request = match method { http::Method::GET => request.get(url), http::Method::POST => request.post(url), http::Method::PUT => request.put(url), @@ -49,16 +50,16 @@ impl ChorusRequest { _ => panic!("Illegal state: Method not supported."), }; if let Some(user) = chorus_user { - let request = request.header("Authorization", user.token()); + request = request.header("Authorization", user.token()); } if let Some(body) = body { // ONCE TOLD ME THE WORLD WAS GONNA ROLL ME - let request = request - .body(to_string(&body).unwrap()) + request = request + .body(body) .header("Content-Type", "application/json"); } if let Some(reason) = audit_log_reason { - let request = request.header("X-Audit-Log-Reason", reason); + request = request.header("X-Audit-Log-Reason", reason); } ChorusRequest { diff --git a/tests/channels.rs b/tests/channels.rs index 94129f6..1647652 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -22,7 +22,7 @@ async fn get_channel() { async fn delete_channel() { let mut bundle = common::setup().await; let channel_guard = bundle.channel.write().unwrap().clone(); - let result = Channel::delete(channel_guard, &mut bundle.user).await; + let result = Channel::delete(channel_guard, None, &mut bundle.user).await; assert!(result.is_ok()); common::teardown(bundle).await } @@ -51,7 +51,10 @@ async fn modify_channel() { default_thread_rate_limit_per_user: None, video_quality_mode: None, }; - let modified_channel = channel.modify(modify_data, &mut bundle.user).await.unwrap(); + let modified_channel = channel + .modify(modify_data, None, &mut bundle.user) + .await + .unwrap(); assert_eq!(modified_channel.name, Some(CHANNEL_NAME.to_string())); let permission_override = PermissionFlags::from_vec(Vec::from([ @@ -66,9 +69,14 @@ async fn modify_channel() { deny: "0".to_string(), }; let channel_id: Snowflake = bundle.channel.read().unwrap().id; - Channel::edit_permissions(&mut bundle.user, channel_id, permission_override.clone()) - .await - .unwrap(); + Channel::modify_permissions( + &mut bundle.user, + channel_id, + None, + permission_override.clone(), + ) + .await + .unwrap(); Channel::delete_permission(&mut bundle.user, channel_id, permission_override.id) .await diff --git a/tests/common/mod.rs b/tests/common/mod.rs index b1f9639..a7b9d5d 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -93,7 +93,7 @@ pub(crate) async fn setup() -> TestBundle { }; let mut user = instance.register_account(®).await.unwrap(); let guild = Guild::create(&mut user, guild_create_schema).await.unwrap(); - let channel = Channel::create(&mut user, guild.id, channel_create_schema) + let channel = Channel::create(&mut user, guild.id, None, channel_create_schema) .await .unwrap(); diff --git a/tests/gateway.rs b/tests/gateway.rs index be1cb10..991c9f2 100644 --- a/tests/gateway.rs +++ b/tests/gateway.rs @@ -44,7 +44,7 @@ async fn test_self_updating_structs() { ..Default::default() }; received_channel - .modify(modify_schema, &mut bundle.user) + .modify(modify_schema, None, &mut bundle.user) .await .unwrap(); assert_eq!( diff --git a/tests/messages.rs b/tests/messages.rs index 43f8c9a..5ad9a89 100644 --- a/tests/messages.rs +++ b/tests/messages.rs @@ -115,7 +115,7 @@ async fn test_stickies() { .unwrap(), Vec::::new() ); - Message::sticky(channel.id, message.id, &mut bundle.user) + Message::sticky(channel.id, message.id, None, &mut bundle.user) .await .unwrap(); assert_eq!( @@ -127,7 +127,7 @@ async fn test_stickies() { .id, message.id ); - Message::unsticky(channel.id, message.id, &mut bundle.user) + Message::unsticky(channel.id, message.id, None, &mut bundle.user) .await .unwrap(); assert_eq!( From 0d93ad8578590b0b5174382ef72da21cbf5284fd Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 01:35:49 +0200 Subject: [PATCH 158/237] Remove unneeded function --- src/lib.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7a957dd..6563bed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,15 +74,6 @@ impl UrlBundle { } } -/// Unwraps an `Option`. Returns an empty string if the String is `None`, or the String contents -/// if it is `Some`. -pub(crate) fn unwrap_empty_if_none(string: Option) -> String { - match string { - Some(str) => str, - None => "".to_string(), - } -} - #[cfg(test)] mod lib { use super::*; From 516a1467fa4e37335c459fcf284e75d418517d17 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 01:35:57 +0200 Subject: [PATCH 159/237] Add some more routes --- src/api/guilds/guilds.rs | 86 ++++++++++++++++++++++++++++++++++++++- src/types/schema/guild.rs | 17 +++++++- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 09afe79..e59f3bc 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -8,8 +8,8 @@ use crate::errors::ChorusResult; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, - GuildModifySchema, GuildPreview, MFALevel, + Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, + GuildMemberSearchSchema, GuildModifySchema, GuildPreview, }; use crate::types::{GuildBan, Snowflake}; @@ -213,6 +213,88 @@ impl Guild { .await?; Ok(response) } + + /// Returns a list of guild member objects that are members of the guild. + /// + /// # Reference + /// See + pub async fn get_members( + guild_id: Snowflake, + user: &mut ChorusUser, + ) -> ChorusResult> { + let request = ChorusRequest::new( + http::Method::GET, + format!( + "{}/guilds/{}/members", + user.belongs_to.borrow().urls.api, + guild_id, + ) + .as_str(), + None, + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.deserialize_response::>(user).await + } + + /// Returns a list of guild member objects whose username or nickname starts with a provided string. + /// + /// # Reference: + /// See + pub async fn search_members( + guild_id: Snowflake, + query: GuildMemberSearchSchema, + user: &mut ChorusUser, + ) -> ChorusResult> { + let mut request = ChorusRequest::new( + http::Method::GET, + format!( + "{}/guilds/{}/members/search", + user.belongs_to.borrow().urls.api, + guild_id, + ) + .as_str(), + None, + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.request = request + .request + .query(&[("query", to_string(&query).unwrap())]); + request.deserialize_response::>(user).await + } + + /// Removes a member from a guild. Requires the KICK_MEMBERS permission. Returns a 204 empty response on success. + /// + /// # Reference + /// See + pub async fn remove_member( + guild_id: Snowflake, + member_id: Snowflake, + audit_log_reason: Option, + user: &mut ChorusUser, + ) -> ChorusResult<()> { + let request = ChorusRequest::new( + http::Method::DELETE, + format!( + "{}/guilds/{}/members/{}", + user.belongs_to.borrow().urls.api, + guild_id, + member_id, + ) + .as_str(), + None, + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.handle_request_as_result(user).await + } } impl Channel { diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 2622796..34ced20 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -1,5 +1,3 @@ -use std::default; - use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; @@ -93,3 +91,18 @@ pub struct GuildPreview { pub approximate_member_count: u32, pub approximate_presence_count: u32, } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct GuildMemberSearchSchema { + pub query: String, + pub limit: Option, +} + +impl Default for GuildMemberSearchSchema { + fn default() -> Self { + Self { + query: Default::default(), + limit: Some(1), + } + } +} From 7b55590fd0d830dd7c6f0077dc263e8ce397c3a7 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 16:47:28 +0200 Subject: [PATCH 160/237] Add modify_member route --- src/api/guilds/guilds.rs | 32 +++++++++++++++++++++++++++++++- src/types/schema/guild.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index e59f3bc..e2fe66b 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -9,7 +9,7 @@ use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, - GuildMemberSearchSchema, GuildModifySchema, GuildPreview, + GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberSchema, }; use crate::types::{GuildBan, Snowflake}; @@ -295,6 +295,36 @@ impl Guild { ); request.handle_request_as_result(user).await } + + /// Modifies attributes of a guild member. Returns the updated guild member object on success. + /// For required Permissions and an API reference, see: + /// + /// # Reference: + /// + pub async fn modify_member( + guild_id: Snowflake, + member_id: Snowflake, + schema: ModifyGuildMemberSchema, + audit_log_reason: Option, + user: &mut ChorusUser, + ) -> ChorusResult<()> { + let request = ChorusRequest::new( + http::Method::PATCH, + format!( + "{}/guilds/{}/members/{}", + user.belongs_to.borrow().urls.api, + guild_id, + member_id, + ) + .as_str(), + Some(to_string(&schema).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.handle_request_as_result(user).await + } } impl Channel { diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 34ced20..72fbdb3 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -1,3 +1,5 @@ +use bitflags::bitflags; +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; @@ -106,3 +108,31 @@ impl Default for GuildMemberSearchSchema { } } } + +#[derive(Debug, Serialize, Deserialize)] +pub struct ModifyGuildMemberSchema { + pub nick: Option, + pub roles: Option>, + pub mute: Option, + pub deaf: Option, + pub channel_id: Option, + pub communication_disabled_until: Option>, + pub flags: Option, +} + +bitflags! { + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] + /// Represents the flags of a Guild Member. + /// + /// # Reference: + /// See + pub struct GuildMemberFlags: u64 { + const DID_REJOIN = 1 << 0; + const COMPLETED_ONBOARDING = 1 << 1; + const BYPASSES_VERIFICATION = 1 << 2; + const STARTED_ONBOARDING = 1 << 3; + const GUEST = 1 << 3; + const AUTOMOD_QUARANTINED_NAME = 1 << 7; + const AUTOMOD_QUARANTINED_BIO = 1 << 8; + } +} From cce5b507bcff783b97373ed5aee3a0b04f1519bb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 16:54:41 +0200 Subject: [PATCH 161/237] Add modify_current_member route --- src/api/guilds/guilds.rs | 31 +++++++++++++++++++++++++++++-- src/types/schema/guild.rs | 10 +++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index e2fe66b..547f3cf 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -307,7 +307,7 @@ impl Guild { schema: ModifyGuildMemberSchema, audit_log_reason: Option, user: &mut ChorusUser, - ) -> ChorusResult<()> { + ) -> ChorusResult { let request = ChorusRequest::new( http::Method::PATCH, format!( @@ -323,7 +323,34 @@ impl Guild { Some(user), LimitType::Guild(guild_id), ); - request.handle_request_as_result(user).await + request.deserialize_response::(user).await + } + + /// Modifies the current user's member in the guild. + /// + /// # Reference: + /// See + pub async fn modify_current_member( + guild_id: Snowflake, + schema: ModifyGuildMemberSchema, + audit_log_reason: Option, + user: &mut ChorusUser, + ) -> ChorusResult { + let request = ChorusRequest::new( + http::Method::PATCH, + format!( + "{}/guilds/{}/members/@me", + user.belongs_to.borrow().urls.api, + guild_id, + ) + .as_str(), + Some(to_string(&schema).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.deserialize_response::(user).await } } diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 72fbdb3..3f5dcea 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -109,7 +109,7 @@ impl Default for GuildMemberSearchSchema { } } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] pub struct ModifyGuildMemberSchema { pub nick: Option, pub roles: Option>, @@ -136,3 +136,11 @@ bitflags! { const AUTOMOD_QUARANTINED_BIO = 1 << 8; } } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct ModifyCurrentGuildMemberSchema { + pub nick: Option, + pub avatar: Option, + pub bio: Option, + pub banner: Option, +} From cd70a5b388ad069b6a69cf2dff57168a6a18bf2e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 17:11:00 +0200 Subject: [PATCH 162/237] Add modify guild member profile route --- src/api/guilds/guilds.rs | 31 ++++++++++++++++++++++++++++++- src/types/entities/user.rs | 14 ++++++++++++++ src/types/schema/guild.rs | 11 +++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 547f3cf..59936b4 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -9,7 +9,8 @@ use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, - GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberSchema, + GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberProfileSchema, + ModifyGuildMemberSchema, UserProfileMetadata, }; use crate::types::{GuildBan, Snowflake}; @@ -352,6 +353,34 @@ impl Guild { ); request.deserialize_response::(user).await } + + /// Modifies the current user's profile in the guild. + /// + /// # Reference: + /// See + pub async fn modify_member_profile( + guild_id: Snowflake, + schema: ModifyGuildMemberProfileSchema, + user: &mut ChorusUser, + ) -> ChorusResult { + let request = ChorusRequest::new( + http::Method::PATCH, + format!( + "{}/guilds/{}/profile/@me", + user.belongs_to.borrow().urls.api, + guild_id, + ) + .as_str(), + Some(to_string(&schema).unwrap()), + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + request + .deserialize_response::(user) + .await + } } impl Channel { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index aadfd35..ed18d2d 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -7,6 +7,8 @@ use std::fmt::Debug; use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{utils::Snowflake, Composite}; +use super::Emoji; + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] pub struct UserData { @@ -120,3 +122,15 @@ bitflags::bitflags! { const BOT_HTTP_INTERACTIONS = 1 << 19; } } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct UserProfileMetadata { + pub guild_id: Option, + pub pronouns: String, + pub bio: Option, + pub banner: Option, + pub accent_color: Option, + pub theme_colors: Option>, + pub popout_animation_particle_type: Option, + pub emoji: Option, +} diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 3f5dcea..51fe423 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -144,3 +144,14 @@ pub struct ModifyCurrentGuildMemberSchema { pub bio: Option, pub banner: Option, } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct ModifyGuildMemberProfileSchema { + pub pronouns: Option, + pub bio: Option, + pub banner: Option, + pub accent_color: Option, + pub theme_colors: Option>, + pub popout_animation_particle_type: Option, + pub emoji_id: Option, +} From 07ebaf6119588b05a47f10665f7b2084d3f03b31 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 17:26:01 +0200 Subject: [PATCH 163/237] Add Get Guild Ban/s, add audit_log_reason to create_ban --- src/api/guilds/guilds.rs | 96 +++++++++++++++++++++++++++++++------- src/types/entities/user.rs | 2 +- src/types/schema/guild.rs | 8 ++++ tests/guilds.rs | 2 + 4 files changed, 89 insertions(+), 19 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 59936b4..2f0c531 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -8,9 +8,9 @@ use crate::errors::ChorusResult; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, - GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberProfileSchema, - ModifyGuildMemberSchema, UserProfileMetadata, + Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildBansQuery, GuildCreateSchema, + GuildMember, GuildMemberSearchSchema, GuildModifySchema, GuildPreview, + ModifyGuildMemberProfileSchema, ModifyGuildMemberSchema, UserProfileMetadata, }; use crate::types::{GuildBan, Snowflake}; @@ -146,24 +146,26 @@ impl Guild { pub async fn create_ban( guild_id: Snowflake, user_id: Snowflake, + audit_log_reason: Option, schema: GuildBanCreateSchema, user: &mut ChorusUser, ) -> ChorusResult { - let chorus_request = ChorusRequest { - request: Client::new() - .put(format!( - "{}/guilds/{}/bans/{}", - user.belongs_to.borrow().urls.api, - guild_id, - user_id - )) - .header("Authorization", user.token()) - .body(to_string(&schema).unwrap()), - limit_type: LimitType::Guild(guild_id), - }; - let response = chorus_request - .deserialize_response::(user) - .await?; + let request = ChorusRequest::new( + http::Method::PUT, + format!( + "{}/guilds/{}/bans/{}", + user.belongs_to.borrow().urls.api, + guild_id, + user_id + ) + .as_str(), + Some(to_string(&schema).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + let response = request.deserialize_response::(user).await?; Ok(response) } @@ -381,6 +383,64 @@ impl Guild { .deserialize_response::(user) .await } + + /// Returns a list of ban objects for the guild. Requires the `BAN_MEMBERS` permission. + /// + /// # Reference: + /// See + pub async fn get_bans( + user: &mut ChorusUser, + guild_id: Snowflake, + query: Option, + ) -> ChorusResult> { + let url = format!( + "{}/guilds/{}/bans", + user.belongs_to.borrow_mut().urls.api, + guild_id, + ); + + let mut request = ChorusRequest::new( + http::Method::GET, + &url, + None, + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + if let Some(query) = query { + request.request = request.request.query(&to_string(&query).unwrap()); + } + request.deserialize_response::>(user).await + } + + /// Returns a ban object for the given user. Requires the `BAN_MEMBERS` permission. + /// + /// # Reference: + /// See + pub async fn get_ban( + user: &mut ChorusUser, + guild_id: Snowflake, + user_id: Snowflake, + ) -> ChorusResult { + let url = format!( + "{}/guilds/{}/bans/{}", + user.belongs_to.borrow_mut().urls.api, + guild_id, + user_id + ); + + let request = ChorusRequest::new( + http::Method::GET, + &url, + None, + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.deserialize_response::(user).await + } } impl Channel { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index ed18d2d..64334ff 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -123,7 +123,7 @@ bitflags::bitflags! { } } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)] pub struct UserProfileMetadata { pub guild_id: Option, pub pronouns: String, diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 51fe423..56c0f9e 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -155,3 +155,11 @@ pub struct ModifyGuildMemberProfileSchema { pub popout_animation_particle_type: Option, pub emoji_id: Option, } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +/// The limit argument is a number between 1 and 1000. +pub struct GuildBansQuery { + pub before: Option, + pub after: Option, + pub limit: Option, +} diff --git a/tests/guilds.rs b/tests/guilds.rs index 8ae6596..c87e68d 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -53,6 +53,7 @@ async fn guild_create_ban() { Guild::create_ban( guild.id, other_user_id, + None, GuildBanCreateSchema::default(), &mut bundle.user, ) @@ -61,6 +62,7 @@ async fn guild_create_ban() { assert!(Guild::create_ban( guild.id, other_user_id, + None, GuildBanCreateSchema::default(), &mut bundle.user, ) From 1709e85a4bff31a886ee311cd9ef23f19c3665c9 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 17:28:02 +0200 Subject: [PATCH 164/237] Add delete_guild_ban --- src/api/guilds/guilds.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 2f0c531..0d66686 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -441,6 +441,35 @@ impl Guild { ); request.deserialize_response::(user).await } + + /// Removes the ban for a user. Requires the BAN_MEMBERS permissions. Returns a 204 empty response on success. + /// + /// # Reference: + /// See + pub async fn delete_ban( + user: &mut ChorusUser, + guild_id: Snowflake, + user_id: Snowflake, + audit_log_reason: Option, + ) -> ChorusResult<()> { + let url = format!( + "{}/guilds/{}/bans/{}", + user.belongs_to.borrow_mut().urls.api, + guild_id, + user_id + ); + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.handle_request_as_result(user).await + } } impl Channel { From cbb24549d2266ceb6a86a6e65e606be0f9312768 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 20:58:46 +0200 Subject: [PATCH 165/237] Add code coverage using coveralls and tarpaulin --- .github/workflows/build_and_test.yml | 8 ++++---- README.md | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 166d4c8..b040ca6 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -31,7 +31,7 @@ jobs: npm run start & working-directory: ./server - uses: Swatinem/rust-cache@v2 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose + - name: Build, Test and Publish Coverage + run: | + cargo install cargo-tarpaulin + cargo tarpaulin --all-features --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 diff --git a/README.md b/README.md index ac8f177..53bf008 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Discord]][Discord-invite] [![Build][build-shield]][build-url] +[![Coverage][coverage-shield]][coverage-url] [![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Issues][issues-shield]][issues-url] @@ -124,6 +125,8 @@ accepted, if it violates these guidelines or [our Code of Conduct](https://githu [clippy-url]: https://github.com/polyphony-chat/chorus/blob/main/.github/workflows/clippy.yml [contributors-shield]: https://img.shields.io/github/contributors/polyphony-chat/chorus.svg?style=flat [contributors-url]: https://github.com/polyphony-chat/chorus/graphs/contributors + [coverage-shield]: https://coveralls.io/repos/github/polyphony-chat/chorus/badge.svg?branch=main + [coverage-url]: https://coveralls.io/github/polyphony-chat/chorus?branch=main [forks-shield]: https://img.shields.io/github/forks/polyphony-chat/chorus.svg?style=flat [forks-url]: https://github.com/polyphony-chat/chorus/network/members [stars-shield]: https://img.shields.io/github/stars/polyphony-chat/chorus.svg?style=flat From 09a70a087ef5b9973c57cb6129fb737d0a0173e0 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 21:07:16 +0200 Subject: [PATCH 166/237] Add CI environment --- .github/workflows/build_and_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index b040ca6..c323536 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -13,6 +13,7 @@ jobs: rust: runs-on: ubuntu-latest + environment: CI steps: - uses: actions/checkout@v3 From 408caec31a4d4f9c6e20007dbeab56a37ec8fc47 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 21:30:07 +0200 Subject: [PATCH 167/237] Bump Node version to 18 --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index c323536..340dbac 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -22,7 +22,7 @@ jobs: git clone https://github.com/bitfl0wer/server.git - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 cache: 'npm' cache-dependency-path: server/package-lock.json - name: Prepare and start Spacebar server From 88a15a05fe6ffe30ce2c15e48956a3c6e26228f6 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 13:32:35 +0200 Subject: [PATCH 168/237] Configure rust-cache --- .github/workflows/build_and_test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 340dbac..a6c68b8 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -32,6 +32,9 @@ jobs: npm run start & working-directory: ./server - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + cache-directories: "~/.cargo/bin/" - name: Build, Test and Publish Coverage run: | cargo install cargo-tarpaulin From b06880b181b39996f3c41284a7f7edbf2d59a369 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 13:37:42 +0200 Subject: [PATCH 169/237] Remove .cargo/bin as it is redundant .cargo is already being cached by rust-cache --- .github/workflows/build_and_test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index a6c68b8..8b8453d 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -34,7 +34,6 @@ jobs: - uses: Swatinem/rust-cache@v2 with: cache-all-crates: "true" - cache-directories: "~/.cargo/bin/" - name: Build, Test and Publish Coverage run: | cargo install cargo-tarpaulin From 0cbc6bf4c66926695d702313ba9271710bdef0f2 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 13:40:56 +0200 Subject: [PATCH 170/237] include cargo-tarpaulin in dev-dependencies --- Cargo.lock | 758 ++++++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 1 + 2 files changed, 723 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e8be43..9d0a5bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.7.6" @@ -69,6 +75,21 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + [[package]] name = "async-trait" version = "0.1.71" @@ -89,6 +110,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -106,7 +138,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.31.1", "rustc-demangle", ] @@ -170,11 +202,85 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-tarpaulin" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2821fc5908848fcabe7b269cc92450baf7c240592e394209d58c790166e6a69" +dependencies = [ + "cargo_metadata", + "cfg-if", + "chrono", + "clap", + "coveralls-api", + "fallible-iterator 0.3.0", + "gimli", + "git2", + "glob", + "humantime-serde", + "indexmap 1.8.2", + "lazy_static", + "libc", + "llvm_profparser", + "nix", + "num_cpus", + "object 0.31.1", + "proc-macro2", + "procfs", + "quick-xml", + "quote", + "regex", + "rustc-demangle", + "rustc_version", + "serde", + "serde_json", + "syn 1.0.109", + "toml 0.7.6", + "tracing", + "tracing-subscriber", + "walkdir", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -189,6 +295,7 @@ dependencies = [ "async-trait", "base64 0.21.2", "bitflags 2.3.3", + "cargo-tarpaulin", "chorus-macros", "chrono", "custom_error", @@ -250,6 +357,21 @@ dependencies = [ "envmnt", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "const-oid" version = "0.7.1" @@ -272,6 +394,20 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "coveralls-api" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94c45ef25d64e6b7229f6e4e0c3c2feeacfff3ad65b1dff162aefc43b2e6157d" +dependencies = [ + "curl", + "deflate", + "md5", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -296,6 +432,15 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -335,6 +480,36 @@ dependencies = [ "typenum", ] +[[package]] +name = "curl" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi", +] + +[[package]] +name = "curl-sys" +version = "0.4.65+curl-8.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "winapi", +] + [[package]] name = "custom_error" version = "1.9.2" @@ -361,7 +536,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 2.0.28", ] @@ -382,6 +557,17 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", + "gzip-header", +] + [[package]] name = "der" version = "0.5.1" @@ -431,7 +617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2d328fc287c61314c4a61af7cfdcbd7e678e39778488c7cb13ec133ce0f4059" dependencies = [ "fsio", - "indexmap 1.9.3", + "indexmap 1.8.2", ] [[package]] @@ -448,7 +634,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -467,6 +653,18 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + [[package]] name = "fastrand" version = "1.9.0" @@ -476,6 +674,16 @@ dependencies = [ "instant", ] +[[package]] +name = "flate2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flume" version = "0.10.14" @@ -635,6 +843,41 @@ name = "gimli" version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +dependencies = [ + "fallible-iterator 0.2.0", + "indexmap 1.8.2", + "stable_deref_trait", +] + +[[package]] +name = "git2" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gzip-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0131feb3d3bb2a5a238d8a4d09f6353b7ebfdc52e77bccbf4ea6eaa751dde639" +dependencies = [ + "crc32fast", +] [[package]] name = "h2" @@ -648,7 +891,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 1.8.2", "slab", "tokio", "tokio-util", @@ -657,9 +900,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "hashbrown" @@ -714,6 +957,15 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.2" @@ -771,6 +1023,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + [[package]] name = "hyper" version = "0.14.27" @@ -849,12 +1117,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.3" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" dependencies = [ "autocfg", - "hashbrown 0.12.3", + "hashbrown 0.11.2", "serde", ] @@ -883,9 +1151,9 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -915,6 +1183,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.64" @@ -947,12 +1224,32 @@ dependencies = [ "spin 0.5.2", ] +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + [[package]] name = "libc" version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "libgit2-sys" +version = "0.15.2+1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + [[package]] name = "libm" version = "0.2.7" @@ -970,12 +1267,61 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "linux-raw-sys" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "llvm_profparser" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7b6560e2d1f5775a688cf48bb560a377f06232a4d8f6f2af903f84e03000c3" +dependencies = [ + "anyhow", + "flate2", + "indexmap 1.8.2", + "leb128", + "md5", + "nom", + "object 0.26.2", + "thiserror", + "tracing", +] + [[package]] name = "lock_api" version = "0.4.10" @@ -998,6 +1344,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.5.0" @@ -1043,7 +1404,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1070,6 +1431,18 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0" +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "static_assertions", +] + [[package]] name = "nom" version = "7.1.3" @@ -1145,17 +1518,29 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", ] +[[package]] +name = "object" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" +dependencies = [ + "flate2", + "memchr", +] + [[package]] name = "object" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ + "flate2", "memchr", + "ruzstd", ] [[package]] @@ -1253,7 +1638,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.1", ] [[package]] @@ -1412,6 +1797,30 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "procfs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943ca7f9f29bab5844ecd8fdb3992c5969b6622bb9609b9502fef9b4310e3f1f" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "chrono", + "flate2", + "hex", + "lazy_static", + "rustix 0.36.15", +] + +[[package]] +name = "quick-xml" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.31" @@ -1477,8 +1886,17 @@ checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.3.3", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1489,9 +1907,15 @@ checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.4", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.7.4" @@ -1586,6 +2010,29 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.36.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.1.4", + "windows-sys 0.45.0", +] + [[package]] name = "rustix" version = "0.37.23" @@ -1596,8 +2043,8 @@ dependencies = [ "errno", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", ] [[package]] @@ -1609,7 +2056,18 @@ dependencies = [ "ci_info", "getopts", "nias", - "toml", + "toml 0.5.11", +] + +[[package]] +name = "ruzstd" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe" +dependencies = [ + "byteorder", + "thiserror", + "twox-hash", ] [[package]] @@ -1618,13 +2076,22 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1656,6 +2123,15 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +dependencies = [ + "serde", +] + [[package]] name = "serde" version = "1.0.171" @@ -1709,6 +2185,15 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1730,7 +2215,7 @@ dependencies = [ "base64 0.21.2", "chrono", "hex", - "indexmap 1.9.3", + "indexmap 1.8.2", "serde", "serde_json", "serde_with_macros", @@ -1771,6 +2256,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1888,7 +2382,7 @@ dependencies = [ "generic-array", "hashlink", "hex", - "indexmap 1.9.3", + "indexmap 1.8.2", "ipnetwork", "itoa", "libc", @@ -1944,6 +2438,18 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stringprep" version = "0.1.3" @@ -1954,6 +2460,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "strsim" version = "0.10.0" @@ -1998,8 +2510,17 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", - "windows-sys", + "rustix 0.37.23", + "windows-sys 0.48.0", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", ] [[package]] @@ -2022,6 +2543,16 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.1.45" @@ -2092,7 +2623,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2164,11 +2695,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml_datetime" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -2177,6 +2723,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -2217,6 +2765,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2245,6 +2824,16 @@ dependencies = [ "utf-8", ] +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + [[package]] name = "typenum" version = "1.16.0" @@ -2331,18 +2920,40 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -2456,6 +3067,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2468,7 +3088,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", ] [[package]] @@ -2477,7 +3106,22 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -2486,51 +3130,93 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index e87e747..80ead12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,3 +50,4 @@ chorus-macros = { path = "chorus-macros" } tokio = { version = "1.29.1", features = ["full"] } lazy_static = "1.4.0" rusty-hook = "0.11.2" +cargo-tarpaulin = "0.26.1" From bf2b8a856ba0f164668ef66d8ebc5d57ed87a87b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 13:43:00 +0200 Subject: [PATCH 171/237] Try removing explicit cargo install call to see what happens --- .github/workflows/build_and_test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 8b8453d..a31b9d7 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -36,5 +36,4 @@ jobs: cache-all-crates: "true" - name: Build, Test and Publish Coverage run: | - cargo install cargo-tarpaulin cargo tarpaulin --all-features --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 From 62fccd13055776033dc2dedeb076ca199fae4088 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 13:45:44 +0200 Subject: [PATCH 172/237] Maybe cargo binstall can help here --- .github/workflows/build_and_test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index a31b9d7..bf48609 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -36,4 +36,6 @@ jobs: cache-all-crates: "true" - name: Build, Test and Publish Coverage run: | + curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash + cargo binstall cargo-tarpaulin cargo tarpaulin --all-features --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 From bf9233fef24b67d5d1323998d0e5f2544314e92b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 13:48:15 +0200 Subject: [PATCH 173/237] Add --no-confirm flag --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index bf48609..0a925dd 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -37,5 +37,5 @@ jobs: - name: Build, Test and Publish Coverage run: | curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash - cargo binstall cargo-tarpaulin + cargo binstall --no-confirm cargo-tarpaulin cargo tarpaulin --all-features --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 From 34ee9f7d6d0d0282a427f9c9ba27a788f9b64d5f Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 14:05:34 +0200 Subject: [PATCH 174/237] as if forcing it does the trick here --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 0a925dd..4ef1d48 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -37,5 +37,5 @@ jobs: - name: Build, Test and Publish Coverage run: | curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash - cargo binstall --no-confirm cargo-tarpaulin + cargo binstall --no-confirm cargo-tarpaulin --force cargo tarpaulin --all-features --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 From b101df9ec94899335850c0eabc932cf51e893872 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 14:09:23 +0200 Subject: [PATCH 175/237] Remove tarpaulin from deps --- Cargo.lock | 740 ++--------------------------------------------------- Cargo.toml | 1 - 2 files changed, 27 insertions(+), 714 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d0a5bc..5cbfe34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,12 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "ahash" version = "0.7.6" @@ -75,21 +69,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" - [[package]] name = "async-trait" version = "0.1.71" @@ -110,17 +89,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -138,7 +106,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.31.1", + "object", "rustc-demangle", ] @@ -202,85 +170,11 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" -[[package]] -name = "camino" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-tarpaulin" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2821fc5908848fcabe7b269cc92450baf7c240592e394209d58c790166e6a69" -dependencies = [ - "cargo_metadata", - "cfg-if", - "chrono", - "clap", - "coveralls-api", - "fallible-iterator 0.3.0", - "gimli", - "git2", - "glob", - "humantime-serde", - "indexmap 1.8.2", - "lazy_static", - "libc", - "llvm_profparser", - "nix", - "num_cpus", - "object 0.31.1", - "proc-macro2", - "procfs", - "quick-xml", - "quote", - "regex", - "rustc-demangle", - "rustc_version", - "serde", - "serde_json", - "syn 1.0.109", - "toml 0.7.6", - "tracing", - "tracing-subscriber", - "walkdir", -] - -[[package]] -name = "cargo_metadata" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -dependencies = [ - "jobserver", -] [[package]] name = "cfg-if" @@ -295,7 +189,6 @@ dependencies = [ "async-trait", "base64 0.21.2", "bitflags 2.3.3", - "cargo-tarpaulin", "chorus-macros", "chrono", "custom_error", @@ -357,21 +250,6 @@ dependencies = [ "envmnt", ] -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap", - "unicode-width", - "vec_map", -] - [[package]] name = "const-oid" version = "0.7.1" @@ -394,20 +272,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "coveralls-api" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c45ef25d64e6b7229f6e4e0c3c2feeacfff3ad65b1dff162aefc43b2e6157d" -dependencies = [ - "curl", - "deflate", - "md5", - "serde", - "serde_derive", - "serde_json", -] - [[package]] name = "cpufeatures" version = "0.2.9" @@ -432,15 +296,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -480,36 +335,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "curl" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" -dependencies = [ - "curl-sys", - "libc", - "openssl-probe", - "openssl-sys", - "schannel", - "socket2", - "winapi", -] - -[[package]] -name = "curl-sys" -version = "0.4.65+curl-8.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", - "winapi", -] - [[package]] name = "custom_error" version = "1.9.2" @@ -536,7 +361,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn 2.0.28", ] @@ -557,17 +382,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" -[[package]] -name = "deflate" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" -dependencies = [ - "adler32", - "byteorder", - "gzip-header", -] - [[package]] name = "der" version = "0.5.1" @@ -634,7 +448,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -653,18 +467,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - [[package]] name = "fastrand" version = "1.9.0" @@ -674,16 +476,6 @@ dependencies = [ "instant", ] -[[package]] -name = "flate2" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "flume" version = "0.10.14" @@ -843,41 +635,6 @@ name = "gimli" version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" -dependencies = [ - "fallible-iterator 0.2.0", - "indexmap 1.8.2", - "stable_deref_trait", -] - -[[package]] -name = "git2" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044" -dependencies = [ - "bitflags 1.3.2", - "libc", - "libgit2-sys", - "log", - "openssl-probe", - "openssl-sys", - "url", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "gzip-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0131feb3d3bb2a5a238d8a4d09f6353b7ebfdc52e77bccbf4ea6eaa751dde639" -dependencies = [ - "crc32fast", -] [[package]] name = "h2" @@ -957,15 +714,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.2" @@ -1023,22 +771,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "humantime-serde" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" -dependencies = [ - "humantime", - "serde", -] - [[package]] name = "hyper" version = "0.14.27" @@ -1151,9 +883,9 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1183,15 +915,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" version = "0.3.64" @@ -1224,32 +947,12 @@ dependencies = [ "spin 0.5.2", ] -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - [[package]] name = "libc" version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "libgit2-sys" -version = "0.15.2+1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa" -dependencies = [ - "cc", - "libc", - "libssh2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", -] - [[package]] name = "libm" version = "0.2.7" @@ -1267,61 +970,12 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "libssh2-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "libz-sys" -version = "1.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linux-raw-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" - [[package]] name = "linux-raw-sys" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" -[[package]] -name = "llvm_profparser" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7b6560e2d1f5775a688cf48bb560a377f06232a4d8f6f2af903f84e03000c3" -dependencies = [ - "anyhow", - "flate2", - "indexmap 1.8.2", - "leb128", - "md5", - "nom", - "object 0.26.2", - "thiserror", - "tracing", -] - [[package]] name = "lock_api" version = "0.4.10" @@ -1344,21 +998,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -[[package]] -name = "matchers" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - [[package]] name = "memchr" version = "2.5.0" @@ -1404,7 +1043,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1431,18 +1070,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0" -[[package]] -name = "nix" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "static_assertions", -] - [[package]] name = "nom" version = "7.1.3" @@ -1518,29 +1145,17 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi", "libc", ] -[[package]] -name = "object" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" -dependencies = [ - "flate2", - "memchr", -] - [[package]] name = "object" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ - "flate2", "memchr", - "ruzstd", ] [[package]] @@ -1638,7 +1253,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets 0.48.1", + "windows-targets", ] [[package]] @@ -1797,30 +1412,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "procfs" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943ca7f9f29bab5844ecd8fdb3992c5969b6622bb9609b9502fef9b4310e3f1f" -dependencies = [ - "bitflags 1.3.2", - "byteorder", - "chrono", - "flate2", - "hex", - "lazy_static", - "rustix 0.36.15", -] - -[[package]] -name = "quick-xml" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" -dependencies = [ - "memchr", -] - [[package]] name = "quote" version = "1.0.31" @@ -1886,17 +1477,8 @@ checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.3", - "regex-syntax 0.7.4", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1907,15 +1489,9 @@ checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.4", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.7.4" @@ -2010,29 +1586,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.36.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.1.4", - "windows-sys 0.45.0", -] - [[package]] name = "rustix" version = "0.37.23" @@ -2043,8 +1596,8 @@ dependencies = [ "errno", "io-lifetimes", "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", + "linux-raw-sys", + "windows-sys", ] [[package]] @@ -2056,18 +1609,7 @@ dependencies = [ "ci_info", "getopts", "nias", - "toml 0.5.11", -] - -[[package]] -name = "ruzstd" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe" -dependencies = [ - "byteorder", - "thiserror", - "twox-hash", + "toml", ] [[package]] @@ -2076,22 +1618,13 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "schannel" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2123,15 +1656,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" -dependencies = [ - "serde", -] - [[package]] name = "serde" version = "1.0.171" @@ -2185,15 +1709,6 @@ dependencies = [ "syn 2.0.28", ] -[[package]] -name = "serde_spanned" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2256,15 +1771,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2438,18 +1944,6 @@ dependencies = [ "tokio-native-tls", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stringprep" version = "0.1.3" @@ -2460,12 +1954,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.10.0" @@ -2510,17 +1998,8 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.23", - "windows-sys 0.48.0", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", + "rustix", + "windows-sys", ] [[package]] @@ -2543,16 +2022,6 @@ dependencies = [ "syn 2.0.28", ] -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - [[package]] name = "time" version = "0.1.45" @@ -2623,7 +2092,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2695,26 +2164,11 @@ dependencies = [ "serde", ] -[[package]] -name = "toml" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - [[package]] name = "toml_datetime" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" @@ -2723,8 +2177,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", - "serde", - "serde_spanned", "toml_datetime", "winnow", ] @@ -2765,37 +2217,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" -dependencies = [ - "ansi_term", - "chrono", - "lazy_static", - "matchers", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", ] [[package]] @@ -2824,16 +2245,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "static_assertions", -] - [[package]] name = "typenum" version = "1.16.0" @@ -2920,40 +2331,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "walkdir" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" version = "0.3.1" @@ -3067,15 +2456,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -3088,16 +2468,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.1", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", + "windows-targets", ] [[package]] @@ -3106,22 +2477,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets", ] [[package]] @@ -3130,93 +2486,51 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 80ead12..e87e747 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,4 +50,3 @@ chorus-macros = { path = "chorus-macros" } tokio = { version = "1.29.1", features = ["full"] } lazy_static = "1.4.0" rusty-hook = "0.11.2" -cargo-tarpaulin = "0.26.1" From 7f4aad891c743b9dc459b1eadaae0d1c3bb92e1c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 14:15:31 +0200 Subject: [PATCH 176/237] Remove tarpaulin rustflags, add --tests --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4ef1d48..304be85 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -38,4 +38,4 @@ jobs: run: | curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash cargo binstall --no-confirm cargo-tarpaulin --force - cargo tarpaulin --all-features --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 + cargo tarpaulin --all-features --avoid-cfg-tarpaulin --tests --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 From 19fc0b4746aed129139a4aafc5097fe41375db23 Mon Sep 17 00:00:00 2001 From: Flori <39242991+bitfl0wer@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:08:47 +0200 Subject: [PATCH 177/237] Remove CI env --- .github/workflows/build_and_test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 304be85..d844256 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -13,8 +13,7 @@ jobs: rust: runs-on: ubuntu-latest - environment: CI - + steps: - uses: actions/checkout@v3 - name: Clone spacebar server From f120bcd3868291ab9813bbc2dd520c6633280712 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 16:21:47 +0200 Subject: [PATCH 178/237] Update GuildBan object --- src/types/entities/guild.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index b6f3cd4..93b13fc 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -16,6 +16,8 @@ use crate::types::{ }; use bitflags::bitflags; +use super::PublicUser; + /// See #[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] @@ -106,8 +108,7 @@ pub struct Guild { #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildBan { - pub user_id: Snowflake, - pub guild_id: Snowflake, + pub user: PublicUser, pub reason: Option, } From 116f1312e70a58699cf5fe3f13087bdd09f505cb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 16:22:18 +0200 Subject: [PATCH 179/237] Disambiguate function name --- src/api/guilds/guilds.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 0d66686..4634c9c 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -360,7 +360,7 @@ impl Guild { /// /// # Reference: /// See - pub async fn modify_member_profile( + pub async fn modify_current_member_profile( guild_id: Snowflake, schema: ModifyGuildMemberProfileSchema, user: &mut ChorusUser, From c53ec5341236225127662d0a65c978b518878e00 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 16:22:47 +0200 Subject: [PATCH 180/237] Add kick member spell --- tests/guilds.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/guilds.rs b/tests/guilds.rs index c87e68d..d7e2699 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -85,3 +85,28 @@ async fn modify_guild() { assert_eq!(result.name.unwrap(), "Mycoolguild".to_string()); common::teardown(bundle).await } + +#[tokio::test] +async fn guild_remove_member() { + let mut bundle = common::setup().await; + let channel = bundle.channel.read().unwrap().clone(); + let mut other_user = bundle.create_user("testuser1312").await; + let user = &mut bundle.user; + let create_channel_invite_schema = CreateChannelInviteSchema::default(); + let guild = bundle.guild.read().unwrap().clone(); + let invite = user + .create_channel_invite(create_channel_invite_schema, channel.id) + .await + .unwrap(); + other_user.accept_invite(&invite.code, None).await.unwrap(); + let other_user_id = other_user.object.read().unwrap().id; + Guild::remove_member(guild.id, other_user_id, None, &mut bundle.user) + .await + .unwrap(); + assert!( + Guild::remove_member(guild.id, other_user_id, None, &mut bundle.user,) + .await + .is_err() + ); + common::teardown(bundle).await +} From aee50036a0c38ad32e5c74817431cc37c79a9ce4 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 16:54:24 +0200 Subject: [PATCH 181/237] Add delete_role + test --- src/api/guilds/roles.rs | 29 +++++++++++++++++++++++++++++ tests/roles.rs | 21 +++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index eb837c9..02994f9 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -160,4 +160,33 @@ impl types::RoleObject { .deserialize_response::(user) .await } + + /// Deletes a guild role. Requires the `MANAGE_ROLES` permission. Returns a 204 empty response on success. + /// + /// # Reference: + /// See + pub async fn delete_role( + user: &mut ChorusUser, + guild_id: Snowflake, + role_id: Snowflake, + audit_log_reason: Option, + ) -> ChorusResult<()> { + let url = format!( + "{}/guilds/{}/roles/{}", + user.belongs_to.borrow_mut().urls.api, + guild_id, + role_id + ); + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.handle_request_as_result(user).await + } } diff --git a/tests/roles.rs b/tests/roles.rs index 7876e5d..8691138 100644 --- a/tests/roles.rs +++ b/tests/roles.rs @@ -1,4 +1,4 @@ -use chorus::types::{self, RoleCreateModifySchema}; +use chorus::types::{self, RoleCreateModifySchema, RoleObject}; mod common; @@ -32,7 +32,7 @@ async fn create_and_get_roles() { } #[tokio::test] -async fn get_singular_role() { +async fn get_and_delete_role() { let mut bundle = common::setup().await; let guild_id = bundle.guild.read().unwrap().id; let role_id = bundle.role.read().unwrap().id; @@ -41,5 +41,22 @@ async fn get_singular_role() { .await .unwrap(); assert_eq!(role, same_role); + assert_eq!( + chorus::types::RoleObject::get_all(&mut bundle.user, guild_id) + .await + .unwrap() + .len(), + 2 + ); + RoleObject::delete_role(&mut bundle.user, guild_id, role_id, None) + .await + .unwrap(); + assert_eq!( + chorus::types::RoleObject::get_all(&mut bundle.user, guild_id) + .await + .unwrap() + .len(), + 1 + ); common::teardown(bundle).await } From ea66edc68d8de072c382b5742a74aaa1038f37be Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 17:45:27 +0200 Subject: [PATCH 182/237] Fix guild ban test failing --- src/api/guilds/guilds.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 4634c9c..e420d6a 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -149,7 +149,8 @@ impl Guild { audit_log_reason: Option, schema: GuildBanCreateSchema, user: &mut ChorusUser, - ) -> ChorusResult { + ) -> ChorusResult<()> { + // FIXME: Return GuildBan instead of (). Requires to be resolved. let request = ChorusRequest::new( http::Method::PUT, format!( @@ -165,8 +166,7 @@ impl Guild { Some(user), LimitType::Guild(guild_id), ); - let response = request.deserialize_response::(user).await?; - Ok(response) + request.handle_request_as_result(user).await } /// # Reference From c4bd33205c07f0b49fb6b0adcb50f3b3653e0ab3 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 18:02:21 +0200 Subject: [PATCH 183/237] Conditional skip of code coverage --- .github/workflows/build_and_test.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index d844256..398c52f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -35,6 +35,13 @@ jobs: cache-all-crates: "true" - name: Build, Test and Publish Coverage run: | - curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash - cargo binstall --no-confirm cargo-tarpaulin --force - cargo tarpaulin --all-features --avoid-cfg-tarpaulin --tests --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 + if [ -n "${{ secrets.COVERALLS_REPO_TOKEN }}" ]; then + curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash + cargo binstall --no-confirm cargo-tarpaulin --force + cargo tarpaulin --all-features --avoid-cfg-tarpaulin --tests --verbose --skip-clean --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} --timeout 120 + else + echo "Code Coverage step is skipped on forks!" + cargo build --verbose --all-features + cargo test --verbose --all-features + fi + From 2f9936cfd2754afb8bdbbe05ba3c89f61944ffee Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sat, 26 Aug 2023 19:41:00 +0200 Subject: [PATCH 184/237] Add rustdoc comments --- src/api/mod.rs | 1 + src/errors.rs | 1 + src/gateway.rs | 2 ++ src/instance.rs | 2 ++ src/lib.rs | 4 ++++ src/ratelimiter.rs | 2 ++ src/types/mod.rs | 2 ++ 7 files changed, 14 insertions(+) diff --git a/src/api/mod.rs b/src/api/mod.rs index 9fd954d..7329c50 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,3 +1,4 @@ +//! All of the API's endpoints. pub use channels::messages::*; pub use guilds::*; pub use invites::*; diff --git a/src/errors.rs b/src/errors.rs index bf08772..eebfae3 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,3 +1,4 @@ +//! Contains all the errors that can be returned by the library. use custom_error::custom_error; use reqwest::Error; diff --git a/src/gateway.rs b/src/gateway.rs index d3a748c..8f3392a 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -1,3 +1,5 @@ +//! Gateway connection, communication and handling, as well as object caching and updating. + use crate::errors::GatewayError; use crate::gateway::events::Events; use crate::types::{ diff --git a/src/instance.rs b/src/instance.rs index 7219c03..0e39a24 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -1,3 +1,5 @@ +//! Instance and ChorusUser objects. + use std::cell::RefCell; use std::collections::HashMap; use std::fmt; diff --git a/src/lib.rs b/src/lib.rs index 6563bed..1efa283 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,7 @@ +//! A library for interacting with one or multiple Spacebar-compatible APIs and Gateways. +//! +//! # About +//!Chorus is a Rust library that allows developers to interact with multiple Spacebar-compatible APIs and Gateways simultaneously. The library provides a simple and efficient way to communicate with these services, making it easier for developers to build applications that rely on them. Chorus is open-source and welcomes contributions from the community. #![allow(clippy::module_inception)] use url::{ParseError, Url}; diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 766e68a..5ffedb5 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -1,3 +1,5 @@ +//! Ratelimiter and request handling functionality. + use std::collections::HashMap; use log::{self, debug}; diff --git a/src/types/mod.rs b/src/types/mod.rs index 8554011..6f06ef0 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,3 +1,5 @@ +//! All the types, entities, events and interfaces of the Spacebar API. + pub use config::*; pub use entities::*; pub use errors::*; From 558232c1a22fea9d7ddcb272947261918a230c56 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 27 Aug 2023 00:11:11 +0200 Subject: [PATCH 185/237] replace sqlx-git-custom with sqlx --- Cargo.lock | 430 +++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 4 +- 2 files changed, 286 insertions(+), 148 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cbfe34..1fb20d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,17 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.3" @@ -35,6 +24,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", ] @@ -82,9 +72,9 @@ dependencies = [ [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] @@ -252,9 +242,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "core-foundation" @@ -315,16 +305,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -384,13 +364,13 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "der" -version = "0.5.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", - "crypto-bigint", "pem-rfc7468", + "zeroize", ] [[package]] @@ -400,7 +380,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -414,6 +396,9 @@ name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +dependencies = [ + "serde", +] [[package]] name = "encoding_rs" @@ -461,6 +446,17 @@ dependencies = [ "libc", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -553,15 +549,21 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot", ] +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + [[package]] name = "futures-macro" version = "0.3.28" @@ -592,9 +594,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -667,7 +671,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" dependencies = [ - "ahash 0.8.3", + "ahash", "allocator-api2", ] @@ -726,6 +730,33 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + [[package]] name = "hostname" version = "0.3.1" @@ -896,9 +927,12 @@ checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "ipnetwork" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f84f1612606f3753f205a4e9a2efd6fe5b4c573a6269b2cc6c3003d44a0d127" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] [[package]] name = "itertools" @@ -961,9 +995,9 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libsqlite3-sys" -version = "0.24.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" dependencies = [ "cc", "pkg-config", @@ -998,6 +1032,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + [[package]] name = "memchr" version = "2.5.0" @@ -1208,17 +1251,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -1226,21 +1258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -1251,7 +1269,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets", ] @@ -1273,9 +1291,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.3.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] @@ -1320,24 +1338,23 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs1" -version = "0.3.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78f66c04ccc83dd4486fd46c33896f4e17b24a7a3a6400dedc48ed0ddd72320" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ "der", "pkcs8", - "zeroize", + "spki", ] [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -1359,7 +1376,7 @@ dependencies = [ "http", "hyper", "mime", - "parking_lot 0.12.1", + "parking_lot", "percent-encoding", "pin-project-lite", "poem-derive", @@ -1451,15 +1468,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -1562,11 +1570,12 @@ dependencies = [ [[package]] name = "rsa" -version = "0.6.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf22754c49613d2b3b119f0e5d46e34a2c628a937e3024b8762de4e7d8c710b" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ "byteorder", + "const-oid", "digest", "num-bigint-dig", "num-integer", @@ -1575,7 +1584,8 @@ dependencies = [ "pkcs1", "pkcs8", "rand_core", - "smallvec", + "signature", + "spki", "subtle", "zeroize", ] @@ -1780,6 +1790,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "simple_asn1" version = "0.6.2" @@ -1834,9 +1854,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1855,95 +1875,206 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.6.3" -source = "git+https://github.com/zert3x/sqlx?branch=feature/skip#b417a65842442b177e2abb39f3940a7c95265d90" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e58421b6bc416714d5115a2ca953718f6c621a51b68e4f4922aea5a4391a721" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" -source = "git+https://github.com/zert3x/sqlx?branch=feature/skip#b417a65842442b177e2abb39f3940a7c95265d90" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4cef4251aabbae751a3710927945901ee1d97ee96d757f6880ebb9a79bfd53" dependencies = [ - "ahash 0.7.6", + "ahash", "atoi", - "bitflags 1.3.2", "byteorder", "bytes", "chrono", "crc", "crossbeam-queue", - "digest", "dotenvy", "either", "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.0.0", + "ipnetwork", + "log", + "memchr", + "native-tls", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "208e3165167afd7f3881b16c1ef3f2af69fa75980897aac8874a0696516d12c2" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a4a8336d278c62231d87f24e8a7a74898156e34c1c18942857be2acb29c7dfc" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" +dependencies = [ + "atoi", + "base64 0.21.2", + "bitflags 2.3.3", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" +dependencies = [ + "atoi", + "base64 0.21.2", + "bitflags 2.3.3", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "ipnetwork", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2" +dependencies = [ + "atoi", + "chrono", "flume", "futures-channel", "futures-core", "futures-executor", "futures-intrusive", "futures-util", - "generic-array", - "hashlink", - "hex", - "indexmap 1.8.2", - "ipnetwork", - "itoa", - "libc", "libsqlite3-sys", "log", - "memchr", - "num-bigint", - "once_cell", - "paste", "percent-encoding", - "rand", - "rsa", "serde", - "serde_json", - "sha1", - "sha2", - "smallvec", - "sqlformat", - "sqlx-rt", - "stringprep", - "thiserror", - "tokio-stream", - "url", -] - -[[package]] -name = "sqlx-macros" -version = "0.6.3" -source = "git+https://github.com/zert3x/sqlx?branch=feature/skip#b417a65842442b177e2abb39f3940a7c95265d90" -dependencies = [ - "dotenvy", - "either", - "heck", - "once_cell", - "proc-macro2", - "quote", - "serde_json", - "sha2", "sqlx-core", - "sqlx-rt", - "syn 1.0.109", + "tracing", "url", ] -[[package]] -name = "sqlx-rt" -version = "0.6.3" -source = "git+https://github.com/zert3x/sqlx?branch=feature/skip#b417a65842442b177e2abb39f3940a7c95265d90" -dependencies = [ - "native-tls", - "once_cell", - "tokio", - "tokio-native-tls", -] - [[package]] name = "stringprep" version = "0.1.3" @@ -1997,7 +2128,7 @@ dependencies = [ "autocfg", "cfg-if", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", "windows-sys", ] @@ -2087,7 +2218,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2194,6 +2325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2440,6 +2572,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index e87e747..13ac3f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ hostname = "0.3.1" bitflags = { version = "2.3.3", features = ["serde"] } lazy_static = "1.4.0" poem = { version = "1.3.56", optional = true } -sqlx = { git = "https://github.com/zert3x/sqlx", branch = "feature/skip", features = [ +sqlx = { version = "0.7.1", features = [ "mysql", "sqlite", "json", @@ -44,7 +44,7 @@ thiserror = "1.0.43" jsonwebtoken = "8.3.0" log = "0.4.19" async-trait = "0.1.71" -chorus-macros = { path = "chorus-macros" } +chorus-macros = { path = "chorus-macros", version = "0.1.0" } [dev-dependencies] tokio = { version = "1.29.1", features = ["full"] } From a8769ffca6cb2bbfc6b07c5ed6e94018be938d4a Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 27 Aug 2023 00:51:52 +0200 Subject: [PATCH 186/237] Bump dependencies --- Cargo.lock | 374 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 30 ++--- 2 files changed, 202 insertions(+), 202 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1fb20d8..fb74150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] @@ -61,13 +61,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -87,9 +87,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -108,9 +108,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64ct" @@ -126,9 +126,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" dependencies = [ "serde", ] @@ -162,9 +162,12 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -177,8 +180,8 @@ name = "chorus" version = "0.1.0" dependencies = [ "async-trait", - "base64 0.21.2", - "bitflags 2.3.3", + "base64 0.21.3", + "bitflags 2.4.0", "chorus-macros", "chrono", "custom_error", @@ -212,7 +215,7 @@ version = "0.1.0" dependencies = [ "async-trait", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -342,7 +345,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -353,7 +356,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -373,6 +376,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +dependencies = [ + "serde", +] + [[package]] name = "digest" version = "0.10.7" @@ -393,18 +405,18 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" dependencies = [ "serde", ] [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -416,7 +428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2d328fc287c61314c4a61af7cfdcbd7e678e39778488c7cb13ec133ce0f4059" dependencies = [ "fsio", - "indexmap 1.8.2", + "indexmap 1.9.3", ] [[package]] @@ -427,9 +439,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -465,12 +477,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "flume" @@ -572,7 +581,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -636,15 +645,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -652,7 +661,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.8.2", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -661,9 +670,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" @@ -798,9 +807,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -819,7 +828,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -880,12 +889,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown 0.11.2", + "hashbrown 0.12.3", "serde", ] @@ -897,26 +906,7 @@ checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", "hashbrown 0.14.0", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", + "serde", ] [[package]] @@ -964,7 +954,7 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "pem", "ring", "serde", @@ -1006,9 +996,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" @@ -1022,9 +1012,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "match_cfg" @@ -1125,9 +1115,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1174,9 +1164,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", "libm", @@ -1194,9 +1184,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" dependencies = [ "memchr", ] @@ -1209,9 +1199,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -1230,7 +1220,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -1241,9 +1231,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", @@ -1306,29 +1296,29 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1365,9 +1355,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "poem" -version = "1.3.56" +version = "1.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a56df40b79ebdccf7986b337f9b0e51ac55cd5e9d21fb20b6aa7c7d49741854" +checksum = "f0d92c532a37a9e98c0e9a0411e6852b8acccf9ec07d5e6e450b01cbf947d90b" dependencies = [ "async-trait", "bytes", @@ -1394,14 +1384,14 @@ dependencies = [ [[package]] name = "poem-derive" -version = "1.3.56" +version = "1.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1701f977a2d650a03df42c053686ea0efdb83554f34c7b026b89383c0a1b7846" +checksum = "f5dd58846a1f582215370384c3090c62c9ef188e9d798ffc67ea90d0a1a8a3b8" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.29", ] [[package]] @@ -1431,9 +1421,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1479,9 +1469,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" dependencies = [ "aho-corasick", "memchr", @@ -1491,9 +1481,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" dependencies = [ "aho-corasick", "memchr", @@ -1502,17 +1492,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "bytes", "encoding_rs", "futures-core", @@ -1598,13 +1588,12 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.37.23" +version = "0.38.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "9bfe0f2582b4931a45d1fa608f8a8722e8b3c7ac54dd6d5f3b3212791fedef49" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys", @@ -1645,9 +1634,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -1658,9 +1647,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -1668,9 +1657,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.171" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -1688,20 +1677,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -1710,13 +1699,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -1733,30 +1722,31 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.1.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3" +checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "chrono", "hex", - "indexmap 1.8.2", + "indexmap 1.9.3", + "indexmap 2.0.0", "serde", "serde_json", "serde_with_macros", - "time 0.3.23", + "time 0.3.27", ] [[package]] name = "serde_with_macros" -version = "3.1.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" +checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -1809,14 +1799,14 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.23", + "time 0.3.27", ] [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -1837,6 +1827,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spin" version = "0.5.2" @@ -1975,8 +1975,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" dependencies = [ "atoi", - "base64 0.21.2", - "bitflags 2.3.3", + "base64 0.21.3", + "bitflags 2.4.0", "byteorder", "bytes", "chrono", @@ -2018,8 +2018,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" dependencies = [ "atoi", - "base64 0.21.2", - "bitflags 2.3.3", + "base64 0.21.3", + "bitflags 2.4.0", "byteorder", "chrono", "crc", @@ -2110,9 +2110,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -2121,11 +2121,10 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", "cfg-if", "fastrand", "redox_syscall", @@ -2135,22 +2134,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -2166,10 +2165,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.23" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07" dependencies = [ + "deranged", "itoa", "serde", "time-core", @@ -2184,9 +2184,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9" dependencies = [ "time-core", ] @@ -2208,11 +2208,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -2221,7 +2220,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.3", "tokio-macros", "windows-sys", ] @@ -2234,7 +2233,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -2260,9 +2259,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" +checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", @@ -2339,7 +2338,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -2359,9 +2358,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" dependencies = [ "byteorder", "bytes", @@ -2394,9 +2393,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] @@ -2517,7 +2516,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", "wasm-bindgen-shared", ] @@ -2551,7 +2550,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2620,9 +2619,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -2635,62 +2634,63 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.0" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 13ac3f5..a9168c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,26 +11,26 @@ client = [] [dependencies] tokio = { version = "1.29.1", features = ["macros"] } -serde = { version = "1.0.171", features = ["derive", "rc"] } -serde_json = { version = "1.0.103", features = ["raw_value"] } +serde = { version = "1.0.188", features = ["derive", "rc"] } +serde_json = { version = "1.0.105", features = ["raw_value"] } serde-aux = "4.2.0" -serde_with = "3.0.0" -serde_repr = "0.1.14" -reqwest = { version = "0.11.18", features = ["multipart", "json"] } +serde_with = "3.3.0" +serde_repr = "0.1.16" +reqwest = { version = "0.11.20", features = ["multipart", "json"] } url = "2.4.0" chrono = { version = "0.4.26", features = ["serde"] } -regex = "1.9.1" +regex = "1.9.4" custom_error = "1.9.2" native-tls = "0.2.11" -tokio-tungstenite = { version = "0.19.0", features = ["native-tls"] } +tokio-tungstenite = { version = "0.20.0", features = ["native-tls"] } futures-util = "0.3.28" http = "0.2.9" -openssl = "0.10.55" -base64 = "0.21.2" +openssl = "0.10.56" +base64 = "0.21.3" hostname = "0.3.1" -bitflags = { version = "2.3.3", features = ["serde"] } +bitflags = { version = "2.4.0", features = ["serde"] } lazy_static = "1.4.0" -poem = { version = "1.3.56", optional = true } +poem = { version = "1.3.57", optional = true } sqlx = { version = "0.7.1", features = [ "mysql", "sqlite", @@ -40,13 +40,13 @@ sqlx = { version = "0.7.1", features = [ "runtime-tokio-native-tls", "any", ], optional = true } -thiserror = "1.0.43" +thiserror = "1.0.47" jsonwebtoken = "8.3.0" -log = "0.4.19" -async-trait = "0.1.71" +log = "0.4.20" +async-trait = "0.1.73" chorus-macros = { path = "chorus-macros", version = "0.1.0" } [dev-dependencies] -tokio = { version = "1.29.1", features = ["full"] } +tokio = { version = "1.32.0", features = ["full"] } lazy_static = "1.4.0" rusty-hook = "0.11.2" From 2e4abb468aa2403dff9ef6c4a17a6281b987c2a4 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 27 Aug 2023 00:59:22 +0200 Subject: [PATCH 187/237] Bump chorus-macros deps --- Cargo.toml | 2 +- chorus-macros/Cargo.toml | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a9168c6..04e4b91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" version = "0.1.0" -license = "AGPL-3" +license = "AGPL-3.0" edition = "2021" [features] diff --git a/chorus-macros/Cargo.toml b/chorus-macros/Cargo.toml index dc04a10..098159f 100644 --- a/chorus-macros/Cargo.toml +++ b/chorus-macros/Cargo.toml @@ -2,11 +2,13 @@ name = "chorus-macros" version = "0.1.0" edition = "2021" +license = "AGPL-3.0" +description = "Macros for the chorus crate." [lib] proc-macro = true [dependencies] -quote = "1" -syn = "2" -async-trait = "0.1.71" +quote = "1.0.33" +syn = "2.0.29" +async-trait = "0.1.73" From 3f829246abd8f8543c2485d89f1bd36ce3f8f5cb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 27 Aug 2023 01:00:41 +0200 Subject: [PATCH 188/237] Bump chorus-macros deps --- Cargo.toml | 2 +- chorus-macros/Cargo.lock | 8 ++++---- chorus-macros/Cargo.toml | 8 +++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a9168c6..04e4b91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" version = "0.1.0" -license = "AGPL-3" +license = "AGPL-3.0" edition = "2021" [features] diff --git a/chorus-macros/Cargo.lock b/chorus-macros/Cargo.lock index 0a84f90..17404a2 100644 --- a/chorus-macros/Cargo.lock +++ b/chorus-macros/Cargo.lock @@ -33,18 +33,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "syn" -version = "2.0.27" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", diff --git a/chorus-macros/Cargo.toml b/chorus-macros/Cargo.toml index dc04a10..098159f 100644 --- a/chorus-macros/Cargo.toml +++ b/chorus-macros/Cargo.toml @@ -2,11 +2,13 @@ name = "chorus-macros" version = "0.1.0" edition = "2021" +license = "AGPL-3.0" +description = "Macros for the chorus crate." [lib] proc-macro = true [dependencies] -quote = "1" -syn = "2" -async-trait = "0.1.71" +quote = "1.0.33" +syn = "2.0.29" +async-trait = "0.1.73" From f8c7fc84c4662a3ef46f313ea33d35d431bc719c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 27 Aug 2023 12:49:58 +0200 Subject: [PATCH 189/237] Add website --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index f80a4aa..6d1859c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" repository = "https://github.com/polyphony-chat/chorus" readme = "README.md" keywords = ["spacebar", "discord", "polyphony"] +website = ["https://discord.com/invite/m3FpcapGDD"] [features] From 9224278cd51e1250a6379acda7d6c0529a4c3b50 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 27 Aug 2023 13:21:45 +0200 Subject: [PATCH 190/237] Change Status to Alpha --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53bf008..74dff4c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Issues][issues-shield]][issues-url] - +
From 02212f95e3926a7f7be30e82f0172fa4a5ba69b1 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 28 Aug 2023 12:27:21 +0200 Subject: [PATCH 191/237] Add Debug derives to all structs --- src/api/channels/reactions.rs | 1 + src/gateway.rs | 2 ++ src/ratelimiter.rs | 1 + src/types/entities/message.rs | 2 +- src/types/interfaces/interaction.rs | 2 ++ src/types/schema/message.rs | 1 + 6 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index d44a61c..4685993 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -7,6 +7,7 @@ use crate::{ }; /// Useful metadata for working with [`types::Reaction`], bundled together nicely. +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ReactionMeta { pub message_id: types::Snowflake, pub channel_id: types::Snowflake, diff --git a/src/gateway.rs b/src/gateway.rs index 8f3392a..68205b5 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -329,6 +329,7 @@ impl GatewayHandle { } } +#[derive(Debug)] pub struct Gateway { events: Arc>, heartbeat_handler: HeartbeatHandler, @@ -726,6 +727,7 @@ impl Gateway { /// Handles sending heartbeats to the gateway in another thread #[allow(dead_code)] // FIXME: Remove this, once HeartbeatHandler is used +#[derive(Debug)] struct HeartbeatHandler { /// How ofter heartbeats need to be sent at a minimum pub heartbeat_interval: Duration, diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 5ffedb5..ac7642c 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -16,6 +16,7 @@ use crate::{ /// Chorus' request struct. This struct is used to send rate-limited requests to the Spacebar server. /// See for more information. +#[derive(Debug)] pub struct ChorusRequest { pub request: RequestBuilder, pub limit_type: LimitType, diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index 27a8857..41c4d51 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -124,7 +124,7 @@ pub struct MessageInteraction { pub member: Option>>, } -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Eq, PartialOrd, Ord)] +#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, Eq, PartialOrd, Ord)] pub struct AllowedMention { parse: Vec, roles: Vec, diff --git a/src/types/interfaces/interaction.rs b/src/types/interfaces/interaction.rs index dd131c8..2aa29fd 100644 --- a/src/types/interfaces/interaction.rs +++ b/src/types/interfaces/interaction.rs @@ -24,6 +24,7 @@ pub enum InteractionType { ApplicationCommand = 2, } +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum InteractionResponseType { SelfCommandResponse = 0, Pong = 1, @@ -33,6 +34,7 @@ pub enum InteractionResponseType { AcknowledgeWithSource = 5, } +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] pub struct InteractionApplicationCommandCallbackData { pub tts: bool, pub content: String, diff --git a/src/types/schema/message.rs b/src/types/schema/message.rs index d430e2a..4e34910 100644 --- a/src/types/schema/message.rs +++ b/src/types/schema/message.rs @@ -21,6 +21,7 @@ pub struct MessageSendSchema { pub attachments: Option>, } +#[derive(Debug)] pub enum MessageSearchEndpoint { GuildChannel(Snowflake), Channel(Snowflake), From a8bea5d88125f05fa7b4ef593043dacd7e831349 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 28 Aug 2023 12:27:38 +0200 Subject: [PATCH 192/237] Clippy rules, docs logo --- src/lib.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 1efa283..2edecc2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,18 @@ //! //! # About //!Chorus is a Rust library that allows developers to interact with multiple Spacebar-compatible APIs and Gateways simultaneously. The library provides a simple and efficient way to communicate with these services, making it easier for developers to build applications that rely on them. Chorus is open-source and welcomes contributions from the community. +#![doc( + html_logo_url = "https://raw.githubusercontent.com/polyphony-chat/design/main/branding/polyphony-chorus-round-8bit.png" +)] #![allow(clippy::module_inception)] +#![deny( + missing_debug_implementations, + clippy::extra_unused_lifetimes, + clippy::from_over_into, + clippy::needless_borrow, + clippy::new_without_default, + clippy::useless_conversion +)] use url::{ParseError, Url}; From 54f907b12eefc11ea60f03e260793fa68ae8d54c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 28 Aug 2023 12:39:16 +0200 Subject: [PATCH 193/237] Bump version to 0.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb74150..bc0a0e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.1.0" +version = "0.2.0" dependencies = [ "async-trait", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index 6d1859c..40c67f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.1.0" +version = "0.2.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" From 4bbb22eb312aeebf02838cdb909170b6f10fb854 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 28 Aug 2023 18:12:17 +0200 Subject: [PATCH 194/237] Replace `belongs_to: Rc>` with `Arc>` to make `ChorusUser` `Send` --- src/api/auth/login.rs | 6 ++---- src/api/auth/register.rs | 5 ++--- src/api/channels/channels.rs | 18 ++++++++++------- src/api/channels/messages.rs | 28 +++++++++++++-------------- src/api/channels/permissions.rs | 4 ++-- src/api/channels/reactions.rs | 12 ++++++------ src/api/guilds/guilds.rs | 34 ++++++++++++++++----------------- src/api/guilds/member.rs | 6 +++--- src/api/guilds/roles.rs | 12 ++++++------ src/api/invites/mod.rs | 6 +++--- src/api/users/channels.rs | 5 ++++- src/api/users/guilds.rs | 7 +++++-- src/api/users/relationships.rs | 10 +++++----- src/api/users/users.rs | 31 ++++++++++++++++++++---------- src/instance.rs | 14 +++++++------- src/ratelimiter.rs | 19 ++++++++---------- 16 files changed, 116 insertions(+), 101 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index d5d96e6..a95c3ca 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -1,5 +1,3 @@ -use std::cell::RefCell; -use std::rc::Rc; use std::sync::{Arc, RwLock}; use reqwest::Client; @@ -30,7 +28,7 @@ impl Instance { // request (since login is an instance wide limit), which is why we are just cloning the // instances' limits to pass them on as user_rate_limits later. let mut shell = - ChorusUser::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; + ChorusUser::shell(Arc::new(RwLock::new(self.clone())), "None".to_string()).await; let login_result = chorus_request .deserialize_response::(&mut shell) .await?; @@ -43,7 +41,7 @@ impl Instance { identify.token = login_result.token.clone(); gateway.send_identify(identify).await; let user = ChorusUser::new( - Rc::new(RefCell::new(self.clone())), + Arc::new(RwLock::new(self.clone())), login_result.token, self.clone_limits_if_some(), login_result.settings, diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 43292d9..1a95d3d 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -1,5 +1,4 @@ use std::sync::{Arc, RwLock}; -use std::{cell::RefCell, rc::Rc}; use reqwest::Client; use serde_json::to_string; @@ -35,7 +34,7 @@ impl Instance { // request (since register is an instance wide limit), which is why we are just cloning // the instances' limits to pass them on as user_rate_limits later. let mut shell = - ChorusUser::shell(Rc::new(RefCell::new(self.clone())), "None".to_string()).await; + ChorusUser::shell(Arc::new(RwLock::new(self.clone())), "None".to_string()).await; let token = chorus_request .deserialize_response::(&mut shell) .await? @@ -50,7 +49,7 @@ impl Instance { identify.token = token.clone(); gateway.send_identify(identify).await; let user = ChorusUser::new( - Rc::new(RefCell::new(self.clone())), + Arc::new(RwLock::new(self.clone())), token.clone(), self.clone_limits_if_some(), Arc::new(RwLock::new(settings)), diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 9565877..7250b0e 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -20,7 +20,7 @@ impl Channel { http::Method::GET, &format!( "{}/channels/{}", - user.belongs_to.borrow().urls.api.clone(), + user.belongs_to.read().unwrap().urls.api.clone(), channel_id ), None, @@ -45,7 +45,11 @@ impl Channel { audit_log_reason: Option, user: &mut ChorusUser, ) -> ChorusResult<()> { - let url = format!("{}/channels/{}", user.belongs_to.borrow().urls.api, self.id,); + let url = format!( + "{}/channels/{}", + user.belongs_to.read().unwrap().urls.api, + self.id, + ); let request = ChorusRequest::new( http::Method::DELETE, @@ -83,7 +87,7 @@ impl Channel { let channel_id = self.id; let url = format!( "{}/channels/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id ); @@ -116,7 +120,7 @@ impl Channel { ) -> Result, ChorusError> { let url = format!( "{}/channels/{}/messages", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id ); @@ -149,7 +153,7 @@ impl Channel { let mut request = Client::new() .put(format!( "{}/channels/{}/recipients/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.id, recipient_id )) @@ -177,7 +181,7 @@ impl Channel { ) -> ChorusResult<()> { let url = format!( "{}/channels/{}/recipients/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.id, recipient_id ); @@ -207,7 +211,7 @@ impl Channel { ) -> ChorusResult<()> { let url = format!( "{}/guilds/{}/channels", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id ); diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index dc79f82..960e492 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -23,7 +23,7 @@ impl Message { channel_id: Snowflake, mut message: MessageSendSchema, ) -> ChorusResult { - let url_api = user.belongs_to.borrow().urls.api.clone(); + let url_api = user.belongs_to.read().unwrap().urls.api.clone(); if message.attachments.is_none() { let chorus_request = ChorusRequest { @@ -98,7 +98,7 @@ impl Message { request: Client::new() .get(format!( "{}/{}/messages/search", - &user.belongs_to.borrow().urls.api, + &user.belongs_to.read().unwrap().urls.api, endpoint )) .header("Authorization", user.token()) @@ -142,7 +142,7 @@ impl Message { http::Method::GET, format!( "{}/channels/{}/pins", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id ) .as_str(), @@ -172,7 +172,7 @@ impl Message { http::Method::PUT, format!( "{}/channels/{}/pins/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id ) @@ -199,7 +199,7 @@ impl Message { http::Method::DELETE, format!( "{}/channels/{}/pins/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id ) @@ -226,7 +226,7 @@ impl Message { request: Client::new() .get(format!( "{}/channels/{}/messages/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id )) @@ -249,7 +249,7 @@ impl Message { http::Method::POST, format!( "{}/channels/{}/messages/greet", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, ) .as_str(), @@ -282,7 +282,7 @@ impl Message { http::Method::POST, format!( "{}/channels/{}/messages/{}/ack", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id ) @@ -311,7 +311,7 @@ impl Message { http::Method::POST, format!( "{}/channels/{}/messages/{}/crosspost", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id ) @@ -336,7 +336,7 @@ impl Message { ) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/hide-guild-feed", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id ); @@ -370,7 +370,7 @@ impl Message { ) -> ChorusResult { let url = format!( "{}/channels/{}/messages/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id ); @@ -396,7 +396,7 @@ impl Message { ) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, message_id ); @@ -438,7 +438,7 @@ impl Message { http::Method::POST, format!( "{}/channels/{}/messages/bulk-delete", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, ) .as_str(), @@ -463,7 +463,7 @@ impl Message { http::Method::POST, format!( "{}/channels/{}/pins/ack", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, ) .as_str(), diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index b932e11..7fa8edd 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -28,7 +28,7 @@ impl types::Channel { ) -> ChorusResult<()> { let url = format!( "{}/channels/{}/permissions/{}", - user.belongs_to.borrow_mut().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, overwrite.id ); @@ -70,7 +70,7 @@ impl types::Channel { ) -> ChorusResult<()> { let url = format!( "{}/channels/{}/permissions/{}", - user.belongs_to.borrow_mut().urls.api, + user.belongs_to.read().unwrap().urls.api, channel_id, overwrite_id ); diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index 4685993..81c0366 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -23,7 +23,7 @@ impl ReactionMeta { pub async fn delete_all(&self, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.channel_id, self.message_id ); @@ -51,7 +51,7 @@ impl ReactionMeta { pub async fn get(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.channel_id, self.message_id, emoji @@ -82,7 +82,7 @@ impl ReactionMeta { pub async fn delete_emoji(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.channel_id, self.message_id, emoji @@ -116,7 +116,7 @@ impl ReactionMeta { pub async fn create(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.channel_id, self.message_id, emoji @@ -145,7 +145,7 @@ impl ReactionMeta { pub async fn remove(&self, emoji: &str, user: &mut ChorusUser) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.channel_id, self.message_id, emoji @@ -181,7 +181,7 @@ impl ReactionMeta { ) -> ChorusResult<()> { let url = format!( "{}/channels/{}/messages/{}/reactions/{}/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.channel_id, self.message_id, emoji, diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index e420d6a..8d5f0d6 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -23,7 +23,7 @@ impl Guild { user: &mut ChorusUser, guild_create_schema: GuildCreateSchema, ) -> ChorusResult { - let url = format!("{}/guilds", user.belongs_to.borrow().urls.api); + let url = format!("{}/guilds", user.belongs_to.read().unwrap().urls.api); let chorus_request = ChorusRequest { request: Client::new() .post(url.clone()) @@ -57,7 +57,7 @@ impl Guild { pub async fn delete(user: &mut ChorusUser, guild_id: Snowflake) -> ChorusResult<()> { let url = format!( "{}/guilds/{}/delete", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id ); let chorus_request = ChorusRequest { @@ -99,7 +99,7 @@ impl Guild { request: Client::new() .get(format!( "{}/guilds/{}/channels", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, self.id )) .header("Authorization", user.token()), @@ -133,7 +133,7 @@ impl Guild { request: Client::new() .get(format!( "{}/guilds/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id )) .header("Authorization", user.token()), @@ -155,7 +155,7 @@ impl Guild { http::Method::PUT, format!( "{}/guilds/{}/bans/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, user_id ) @@ -180,7 +180,7 @@ impl Guild { request: Client::new() .patch(format!( "{}/guilds/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, )) .header("Authorization", user.token()) @@ -204,7 +204,7 @@ impl Guild { request: Client::new() .patch(format!( "{}/guilds/{}/preview", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, )) .header("Authorization", user.token()) @@ -229,7 +229,7 @@ impl Guild { http::Method::GET, format!( "{}/guilds/{}/members", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, ) .as_str(), @@ -255,7 +255,7 @@ impl Guild { http::Method::GET, format!( "{}/guilds/{}/members/search", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, ) .as_str(), @@ -285,7 +285,7 @@ impl Guild { http::Method::DELETE, format!( "{}/guilds/{}/members/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, member_id, ) @@ -315,7 +315,7 @@ impl Guild { http::Method::PATCH, format!( "{}/guilds/{}/members/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, member_id, ) @@ -343,7 +343,7 @@ impl Guild { http::Method::PATCH, format!( "{}/guilds/{}/members/@me", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, ) .as_str(), @@ -369,7 +369,7 @@ impl Guild { http::Method::PATCH, format!( "{}/guilds/{}/profile/@me", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, ) .as_str(), @@ -395,7 +395,7 @@ impl Guild { ) -> ChorusResult> { let url = format!( "{}/guilds/{}/bans", - user.belongs_to.borrow_mut().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, ); @@ -425,7 +425,7 @@ impl Guild { ) -> ChorusResult { let url = format!( "{}/guilds/{}/bans/{}", - user.belongs_to.borrow_mut().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, user_id ); @@ -454,7 +454,7 @@ impl Guild { ) -> ChorusResult<()> { let url = format!( "{}/guilds/{}/bans/{}", - user.belongs_to.borrow_mut().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, user_id ); @@ -488,7 +488,7 @@ impl Channel { let mut request = Client::new() .post(format!( "{}/guilds/{}/channels", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id )) .header("Authorization", user.token()) diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index ca81ea1..01294bd 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -20,7 +20,7 @@ impl types::GuildMember { ) -> ChorusResult { let url = format!( "{}/guilds/{}/members/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, member_id ); @@ -47,7 +47,7 @@ impl types::GuildMember { ) -> ChorusResult<()> { let url = format!( "{}/guilds/{}/members/{}/roles/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, member_id, role_id @@ -76,7 +76,7 @@ impl types::GuildMember { ) -> Result<(), crate::errors::ChorusError> { let url = format!( "{}/guilds/{}/members/{}/roles/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, member_id, role_id diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 02994f9..17d6f7b 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -20,7 +20,7 @@ impl types::RoleObject { ) -> ChorusResult> { let url = format!( "{}/guilds/{}/roles", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id ); let chorus_request = ChorusRequest { @@ -45,7 +45,7 @@ impl types::RoleObject { ) -> ChorusResult { let url = format!( "{}/guilds/{}/roles/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, role_id ); @@ -71,7 +71,7 @@ impl types::RoleObject { ) -> ChorusResult { let url = format!( "{}/guilds/{}/roles", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id ); let body = to_string::(&role_create_schema).map_err(|e| { @@ -105,7 +105,7 @@ impl types::RoleObject { ) -> ChorusResult { let url = format!( "{}/guilds/{}/roles", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id ); let body = @@ -139,7 +139,7 @@ impl types::RoleObject { ) -> ChorusResult { let url = format!( "{}/guilds/{}/roles/{}", - user.belongs_to.borrow().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, role_id ); @@ -173,7 +173,7 @@ impl types::RoleObject { ) -> ChorusResult<()> { let url = format!( "{}/guilds/{}/roles/{}", - user.belongs_to.borrow_mut().urls.api, + user.belongs_to.read().unwrap().urls.api, guild_id, role_id ); diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index 88a5705..658fb22 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -22,7 +22,7 @@ impl ChorusUser { request: Client::new() .post(format!( "{}/invites/{}", - self.belongs_to.borrow().urls.api, + self.belongs_to.read().unwrap().urls.api, invite_code )) .header("Authorization", self.token()), @@ -48,7 +48,7 @@ impl ChorusUser { request: Client::new() .post(format!( "{}/users/@me/invites", - self.belongs_to.borrow().urls.api + self.belongs_to.read().unwrap().urls.api )) .body(to_string(&code).unwrap()) .header("Authorization", self.token()) @@ -75,7 +75,7 @@ impl ChorusUser { request: Client::new() .post(format!( "{}/channels/{}/invites", - self.belongs_to.borrow().urls.api, + self.belongs_to.read().unwrap().urls.api, channel_id )) .header("Authorization", self.token()) diff --git a/src/api/users/channels.rs b/src/api/users/channels.rs index 993894f..8d5f063 100644 --- a/src/api/users/channels.rs +++ b/src/api/users/channels.rs @@ -21,7 +21,10 @@ impl ChorusUser { &mut self, create_private_channel_schema: PrivateChannelCreateSchema, ) -> ChorusResult { - let url = format!("{}/users/@me/channels", self.belongs_to.borrow().urls.api); + let url = format!( + "{}/users/@me/channels", + self.belongs_to.read().unwrap().urls.api + ); ChorusRequest { request: Client::new() .post(url) diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index 5e9b921..d2d5b9e 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -20,7 +20,7 @@ impl ChorusUser { request: Client::new() .delete(format!( "{}/users/@me/guilds/{}", - self.belongs_to.borrow().urls.api, + self.belongs_to.read().unwrap().urls.api, guild_id )) .header("Authorization", self.token()) @@ -41,7 +41,10 @@ impl ChorusUser { &mut self, query: Option, ) -> ChorusResult> { - let url = format!("{}/users/@me/guilds", self.belongs_to.borrow().urls.api,); + let url = format!( + "{}/users/@me/guilds", + self.belongs_to.read().unwrap().urls.api, + ); let chorus_request = ChorusRequest { request: Client::new() .get(url) diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index ae4ee27..8988871 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -22,7 +22,7 @@ impl ChorusUser { ) -> ChorusResult> { let url = format!( "{}/users/{}/relationships", - self.belongs_to.borrow().urls.api, + self.belongs_to.read().unwrap().urls.api, user_id ); let chorus_request = ChorusRequest { @@ -41,7 +41,7 @@ impl ChorusUser { pub async fn get_relationships(&mut self) -> ChorusResult> { let url = format!( "{}/users/@me/relationships", - self.belongs_to.borrow().urls.api + self.belongs_to.read().unwrap().urls.api ); let chorus_request = ChorusRequest { request: Client::new().get(url).header("Authorization", self.token()), @@ -62,7 +62,7 @@ impl ChorusUser { ) -> ChorusResult<()> { let url = format!( "{}/users/@me/relationships", - self.belongs_to.borrow().urls.api + self.belongs_to.read().unwrap().urls.api ); let body = to_string(&schema).unwrap(); let chorus_request = ChorusRequest { @@ -84,7 +84,7 @@ impl ChorusUser { user_id: Snowflake, relationship_type: RelationshipType, ) -> ChorusResult<()> { - let api_url = self.belongs_to.borrow().urls.api.clone(); + let api_url = self.belongs_to.read().unwrap().urls.api.clone(); match relationship_type { RelationshipType::None => { let chorus_request = ChorusRequest { @@ -136,7 +136,7 @@ impl ChorusUser { pub async fn remove_relationship(&mut self, user_id: Snowflake) -> ChorusResult<()> { let url = format!( "{}/users/@me/relationships/{}", - self.belongs_to.borrow().urls.api, + self.belongs_to.read().unwrap().urls.api, user_id ); let chorus_request = ChorusRequest { diff --git a/src/api/users/users.rs b/src/api/users/users.rs index d80700e..25ac6cd 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, rc::Rc}; +use std::sync::{Arc, RwLock}; use reqwest::Client; use serde_json::to_string; @@ -48,7 +48,10 @@ impl ChorusUser { return Err(ChorusError::PasswordRequired); } let request = Client::new() - .patch(format!("{}/users/@me", self.belongs_to.borrow().urls.api)) + .patch(format!( + "{}/users/@me", + self.belongs_to.read().unwrap().urls.api + )) .body(to_string(&modify_schema).unwrap()) .header("Authorization", self.token()) .header("Content-Type", "application/json"); @@ -67,7 +70,7 @@ impl ChorusUser { let request = Client::new() .post(format!( "{}/users/@me/delete", - self.belongs_to.borrow().urls.api + self.belongs_to.read().unwrap().urls.api )) .header("Authorization", self.token()) .header("Content-Type", "application/json"); @@ -86,7 +89,7 @@ impl User { /// See and /// pub async fn get(user: &mut ChorusUser, id: Option<&String>) -> ChorusResult { - let url_api = user.belongs_to.borrow().urls.api.clone(); + let url_api = user.belongs_to.read().unwrap().urls.api.clone(); let url = if id.is_none() { format!("{}/users/@me", url_api) } else { @@ -121,7 +124,7 @@ impl User { .get(format!("{}/users/@me/settings", url_api)) .header("Authorization", token); let mut user = - ChorusUser::shell(Rc::new(RefCell::new(instance.clone())), token.clone()).await; + ChorusUser::shell(Arc::new(RwLock::new(instance.clone())), token.clone()).await; let chorus_request = ChorusRequest { request, limit_type: LimitType::Global, @@ -131,8 +134,12 @@ impl User { Err(e) => Err(e), }; if instance.limits_information.is_some() { - instance.limits_information.as_mut().unwrap().ratelimits = - user.belongs_to.borrow().clone_limits_if_some().unwrap(); + instance.limits_information.as_mut().unwrap().ratelimits = user + .belongs_to + .read() + .unwrap() + .clone_limits_if_some() + .unwrap(); } result } @@ -148,11 +155,15 @@ impl Instance { /// See and /// pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult { - let mut user = ChorusUser::shell(Rc::new(RefCell::new(self.clone())), token).await; + let mut user = ChorusUser::shell(Arc::new(RwLock::new(self.clone())), token).await; let result = User::get(&mut user, id).await; if self.limits_information.is_some() { - self.limits_information.as_mut().unwrap().ratelimits = - user.belongs_to.borrow().clone_limits_if_some().unwrap(); + self.limits_information.as_mut().unwrap().ratelimits = user + .belongs_to + .read() + .unwrap() + .clone_limits_if_some() + .unwrap(); } result } diff --git a/src/instance.rs b/src/instance.rs index 0e39a24..08a7f82 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -1,9 +1,8 @@ //! Instance and ChorusUser objects. -use std::cell::RefCell; use std::collections::HashMap; use std::fmt; -use std::rc::Rc; + use std::sync::{Arc, RwLock}; use reqwest::Client; @@ -90,7 +89,7 @@ impl fmt::Display for Token { /// It is used for most authenticated actions on a Spacebar server. /// It also has its own [Gateway] connection. pub struct ChorusUser { - pub belongs_to: Rc>, + pub belongs_to: Arc>, pub token: String, pub limits: Option>, pub settings: Arc>, @@ -113,7 +112,7 @@ impl ChorusUser { /// This isn't the prefered way to create a ChorusUser. /// See [Instance::login_account] and [Instance::register_account] instead. pub fn new( - belongs_to: Rc>, + belongs_to: Arc>, token: String, limits: Option>, settings: Arc>, @@ -135,17 +134,18 @@ impl ChorusUser { /// registering or logging in to the Instance, where you do not yet have a User object, but still /// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify /// first. - pub(crate) async fn shell(instance: Rc>, token: String) -> ChorusUser { + pub(crate) async fn shell(instance: Arc>, token: String) -> ChorusUser { let settings = Arc::new(RwLock::new(UserSettings::default())); let object = Arc::new(RwLock::new(User::default())); - let wss_url = instance.borrow().urls.wss.clone(); + let wss_url = instance.read().unwrap().urls.wss.clone(); // Dummy gateway object let gateway = Gateway::new(wss_url).await.unwrap(); ChorusUser { token, belongs_to: instance.clone(), limits: instance - .borrow() + .read() + .unwrap() .limits_information .as_ref() .map(|info| info.ratelimits.clone()), diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index ac7642c..84bd641 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -82,12 +82,8 @@ impl ChorusRequest { bucket: format!("{:?}", self.limit_type), }); } - let belongs_to = user.belongs_to.borrow(); - let result = match belongs_to - .client - .execute(self.request.build().unwrap()) - .await - { + let client = user.belongs_to.read().unwrap().client.clone(); + let result = match client.execute(self.request.build().unwrap()).await { Ok(result) => { debug!("Request successful: {:?}", result); result @@ -100,12 +96,13 @@ impl ChorusRequest { }); } }; - drop(belongs_to); + drop(client); if !result.status().is_success() { if result.status().as_u16() == 429 { log::warn!("Rate limit hit unexpectedly. Bucket: {:?}. Setting the instances' remaining global limit to 0 to have cooldown.", self.limit_type); user.belongs_to - .borrow_mut() + .write() + .unwrap() .limits_information .as_mut() .unwrap() @@ -126,7 +123,7 @@ impl ChorusRequest { fn can_send_request(user: &mut ChorusUser, limit_type: &LimitType) -> bool { log::trace!("Checking if user or instance is rate-limited..."); - let mut belongs_to = user.belongs_to.borrow_mut(); + let mut belongs_to = user.belongs_to.write().unwrap(); if belongs_to.limits_information.is_none() { log::trace!("Instance indicates no rate limits are configured. Continuing."); return true; @@ -288,7 +285,7 @@ impl ChorusRequest { /// reset to the rate limit limit. /// 2. The remaining rate limit is decreased by 1. fn update_rate_limits(user: &mut ChorusUser, limit_type: &LimitType, response_was_err: bool) { - if user.belongs_to.borrow().limits_information.is_none() { + if user.belongs_to.read().unwrap().limits_information.is_none() { return; } let instance_dictated_limits = [ @@ -311,7 +308,7 @@ impl ChorusRequest { } let time: u64 = chrono::Utc::now().timestamp() as u64; for relevant_limit in relevant_limits.iter() { - let mut belongs_to = user.belongs_to.borrow_mut(); + let mut belongs_to = user.belongs_to.write().unwrap(); let limit = match relevant_limit.0 { LimitOrigin::Instance => { log::trace!( From 60aa559e6d2d6fc82b4aa03cb2139a0ad0521bd2 Mon Sep 17 00:00:00 2001 From: Flori <39242991+bitfl0wer@users.noreply.github.com> Date: Mon, 28 Aug 2023 18:23:30 +0200 Subject: [PATCH 195/237] Update Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 40c67f5..40a7024 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.2.0" +version = "0.3.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" From 2b203f1a423e01dfb3ac9346c13a62d4417dd660 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 28 Aug 2023 18:24:23 +0200 Subject: [PATCH 196/237] Bump version to 0.3.0 --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index bc0a0e0..1ca1da2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.2.0" +version = "0.3.0" dependencies = [ "async-trait", "base64 0.21.3", From 17fe4f004f75d02a684812b1f75cec89894fe65e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 29 Aug 2023 00:05:16 +0200 Subject: [PATCH 197/237] Make ChorusUser `Clone` --- src/instance.rs | 8 ++++---- src/types/schema/auth.rs | 6 +++--- tests/common/mod.rs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index 08a7f82..a3b5325 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -84,7 +84,7 @@ impl fmt::Display for Token { } } -#[derive(Debug)] +#[derive(Debug, Clone)] /// A ChorusUser is a representation of an authenticated user on an [Instance]. /// It is used for most authenticated actions on a Spacebar server. /// It also has its own [Gateway] connection. @@ -94,7 +94,7 @@ pub struct ChorusUser { pub limits: Option>, pub settings: Arc>, pub object: Arc>, - pub gateway: GatewayHandle, + pub gateway: Arc, // TODO: Can this be an Arc? That way we could have Clone implemented on ChorusUser } impl ChorusUser { @@ -117,7 +117,7 @@ impl ChorusUser { limits: Option>, settings: Arc>, object: Arc>, - gateway: GatewayHandle, + gateway: Arc, ) -> ChorusUser { ChorusUser { belongs_to, @@ -139,7 +139,7 @@ impl ChorusUser { let object = Arc::new(RwLock::new(User::default())); let wss_url = instance.read().unwrap().urls.wss.clone(); // Dummy gateway object - let gateway = Gateway::new(wss_url).await.unwrap(); + let gateway = Arc::new(Gateway::new(wss_url).await.unwrap()); ChorusUser { token, belongs_to: instance.clone(), diff --git a/src/types/schema/auth.rs b/src/types/schema/auth.rs index 9a3b9d6..60e23a4 100644 --- a/src/types/schema/auth.rs +++ b/src/types/schema/auth.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub struct RegisterSchema { pub username: String, @@ -15,7 +15,7 @@ pub struct RegisterSchema { pub promotional_email_opt_in: Option, } -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub struct LoginSchema { /// For Discord, usernames must be between 2 and 32 characters, @@ -30,7 +30,7 @@ pub struct LoginSchema { pub gift_code_sku_id: Option, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub struct TotpSchema { code: String, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index a7b9d5d..19c6509 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -42,7 +42,7 @@ impl TestBundle { limits: self.user.limits.clone(), settings: self.user.settings.clone(), object: self.user.object.clone(), - gateway: Gateway::new(self.instance.urls.wss.clone()).await.unwrap(), + gateway: Arc::new(Gateway::new(self.instance.urls.wss.clone()).await.unwrap()), } } } From 00faab480124bf48278e0eb1aa54cac73be2f593 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 29 Aug 2023 00:05:36 +0200 Subject: [PATCH 198/237] Change gateway to Arc::new(gateway) --- src/api/auth/login.rs | 2 +- src/api/auth/register.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index a95c3ca..46951be 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -46,7 +46,7 @@ impl Instance { self.clone_limits_if_some(), login_result.settings, Arc::new(RwLock::new(object)), - gateway, + Arc::new(gateway), ); Ok(user) } diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 1a95d3d..44c29d8 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -54,7 +54,7 @@ impl Instance { self.clone_limits_if_some(), Arc::new(RwLock::new(settings)), Arc::new(RwLock::new(user_object)), - gateway, + Arc::new(gateway), ); Ok(user) } From 387991c605e3539edd362cf5f2aa7bf208c2d00d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 29 Aug 2023 00:06:17 +0200 Subject: [PATCH 199/237] Bump version --- Cargo.lock | 5 +---- Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ca1da2..e902f2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.3.0" +version = "0.4.0" dependencies = [ "async-trait", "base64 0.21.3", @@ -2265,9 +2265,7 @@ checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", - "native-tls", "tokio", - "tokio-native-tls", "tungstenite", ] @@ -2368,7 +2366,6 @@ dependencies = [ "http", "httparse", "log", - "native-tls", "rand", "sha1", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 40a7024..57e0f20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.3.0" +version = "0.4.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" @@ -28,7 +28,7 @@ chrono = { version = "0.4.26", features = ["serde"] } regex = "1.9.4" custom_error = "1.9.2" native-tls = "0.2.11" -tokio-tungstenite = { version = "0.20.0", features = ["native-tls"] } +tokio-tungstenite = { version = "0.20.0", fseatures = ["native-tls"] } futures-util = "0.3.28" http = "0.2.9" openssl = "0.10.56" From 560a0d8fd8f11ab204dd8c86d75539549ed3b16b Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 29 Aug 2023 00:08:59 +0200 Subject: [PATCH 200/237] Fix typo --- Cargo.lock | 3 +++ Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index e902f2d..8c8c26e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2265,7 +2265,9 @@ checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", + "native-tls", "tokio", + "tokio-native-tls", "tungstenite", ] @@ -2366,6 +2368,7 @@ dependencies = [ "http", "httparse", "log", + "native-tls", "rand", "sha1", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 57e0f20..3d2732b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ chrono = { version = "0.4.26", features = ["serde"] } regex = "1.9.4" custom_error = "1.9.2" native-tls = "0.2.11" -tokio-tungstenite = { version = "0.20.0", fseatures = ["native-tls"] } +tokio-tungstenite = { version = "0.20.0", features = ["native-tls"] } futures-util = "0.3.28" http = "0.2.9" openssl = "0.10.56" From 3d8d6b6f3be1d68f36b4b2f065a1f7673e604751 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 14:24:32 +0200 Subject: [PATCH 201/237] Make GatewayHandle Clone --- src/api/auth/login.rs | 2 +- src/api/auth/register.rs | 2 +- src/gateway.rs | 6 ++---- src/instance.rs | 6 +++--- tests/common/mod.rs | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 46951be..a95c3ca 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -46,7 +46,7 @@ impl Instance { self.clone_limits_if_some(), login_result.settings, Arc::new(RwLock::new(object)), - Arc::new(gateway), + gateway, ); Ok(user) } diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 44c29d8..1a95d3d 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -54,7 +54,7 @@ impl Instance { self.clone_limits_if_some(), Arc::new(RwLock::new(settings)), Arc::new(RwLock::new(user_object)), - Arc::new(gateway), + gateway, ); Ok(user) } diff --git a/src/gateway.rs b/src/gateway.rs index 68205b5..ebe5ca2 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -158,7 +158,7 @@ pub type ObservableObject = dyn Send + Sync + Any; /// [`GatewayEvents`](GatewayEvent), which you can subscribe to. Gateway events include all currently /// implemented types with the trait [`WebSocketEvent`] /// Using this handle you can also send Gateway Events directly. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct GatewayHandle { pub url: String, pub events: Arc>, @@ -170,7 +170,6 @@ pub struct GatewayHandle { >, >, >, - pub handle: JoinHandle<()>, /// Tells gateway tasks to close kill_send: tokio::sync::broadcast::Sender<()>, pub(crate) store: Arc>>>>, @@ -410,7 +409,7 @@ impl Gateway { }; // Now we can continuously check for messages in a different task, since we aren't going to receive another hello - let handle: JoinHandle<()> = task::spawn(async move { + task::spawn(async move { gateway.gateway_listen_task().await; }); @@ -418,7 +417,6 @@ impl Gateway { url: websocket_url.clone(), events: shared_events, websocket_send: shared_websocket_send.clone(), - handle, kill_send: kill_send.clone(), store, }) diff --git a/src/instance.rs b/src/instance.rs index a3b5325..8ced86a 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -94,7 +94,7 @@ pub struct ChorusUser { pub limits: Option>, pub settings: Arc>, pub object: Arc>, - pub gateway: Arc, // TODO: Can this be an Arc? That way we could have Clone implemented on ChorusUser + pub gateway: GatewayHandle, } impl ChorusUser { @@ -117,7 +117,7 @@ impl ChorusUser { limits: Option>, settings: Arc>, object: Arc>, - gateway: Arc, + gateway: GatewayHandle, ) -> ChorusUser { ChorusUser { belongs_to, @@ -139,7 +139,7 @@ impl ChorusUser { let object = Arc::new(RwLock::new(User::default())); let wss_url = instance.read().unwrap().urls.wss.clone(); // Dummy gateway object - let gateway = Arc::new(Gateway::new(wss_url).await.unwrap()); + let gateway = Gateway::new(wss_url).await.unwrap(); ChorusUser { token, belongs_to: instance.clone(), diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 19c6509..a7b9d5d 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -42,7 +42,7 @@ impl TestBundle { limits: self.user.limits.clone(), settings: self.user.settings.clone(), object: self.user.object.clone(), - gateway: Arc::new(Gateway::new(self.instance.urls.wss.clone()).await.unwrap()), + gateway: Gateway::new(self.instance.urls.wss.clone()).await.unwrap(), } } } From 98b3d510e4802f7ef043f5ef30940eb6254fb37c Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 14:44:47 +0200 Subject: [PATCH 202/237] Test error observer --- src/errors.rs | 7 ++++++- src/gateway.rs | 9 ++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index eebfae3..26cc6b2 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -2,6 +2,8 @@ use custom_error::custom_error; use reqwest::Error; +use crate::types::WebSocketEvent; + custom_error! { #[derive(PartialEq, Eq)] pub RegistrationError @@ -54,9 +56,10 @@ custom_error! { /// Supposed to be sent as numbers, though they are sent as string most of the time? /// /// Also includes errors when initiating a connection and unexpected opcodes - #[derive(PartialEq, Eq)] + #[derive(PartialEq, Eq, Default)] pub GatewayError // Errors we have received from the gateway + #[default] Unknown = "We're not sure what went wrong. Try reconnecting?", UnknownOpcode = "You sent an invalid Gateway opcode or an invalid payload for an opcode", Decode = "Gateway server couldn't decode payload", @@ -79,3 +82,5 @@ custom_error! { // Other misc errors UnexpectedOpcodeReceived{opcode: u8} = "Received an opcode we weren't expecting to receive: {opcode}", } + +impl WebSocketEvent for GatewayError {} diff --git a/src/gateway.rs b/src/gateway.rs index 68205b5..6913e6a 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -481,13 +481,15 @@ impl Gateway { return; } - // Todo: handle errors in a good way, maybe observers like events? if msg.is_error() { - warn!("GW: Received error, connection will close.."); + let error = msg.error().unwrap(); - let _error = msg.error(); + warn!("GW: Received error {:?}, connection will close..", error); self.close().await; + + self.events.lock().await.error.notify(error).await; + return; } @@ -937,6 +939,7 @@ mod events { pub webhooks: Webhooks, pub gateway_identify_payload: GatewayEvent, pub gateway_resume: GatewayEvent, + pub error: GatewayEvent, } #[derive(Default, Debug)] From 8c45355620d66156ae8788ab0458eb674dbdbf37 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 29 Aug 2023 14:45:10 +0200 Subject: [PATCH 203/237] Bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c8c26e..8a1e22a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.4.0" +version = "0.5.0" dependencies = [ "async-trait", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index 3d2732b..312d9e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.4.0" +version = "0.5.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" From ec2cee58a8381e47825334b7f46bebe593211dfb Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:49:30 +0200 Subject: [PATCH 204/237] Minor updates --- src/errors.rs | 2 +- src/types/events/call.rs | 6 +++--- src/types/events/identify.rs | 4 ++-- src/types/events/presence.rs | 4 ++-- src/types/events/user.rs | 6 +++--- src/types/events/webrtc/ready.rs | 2 +- src/types/interfaces/activity.rs | 12 ++++++------ 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 26cc6b2..642a3ba 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -56,7 +56,7 @@ custom_error! { /// Supposed to be sent as numbers, though they are sent as string most of the time? /// /// Also includes errors when initiating a connection and unexpected opcodes - #[derive(PartialEq, Eq, Default)] + #[derive(PartialEq, Eq, Default, Clone)] pub GatewayError // Errors we have received from the gateway #[default] diff --git a/src/types/events/call.rs b/src/types/events/call.rs index e37c19d..508aae2 100644 --- a/src/types/events/call.rs +++ b/src/types/events/call.rs @@ -21,7 +21,7 @@ pub struct CallCreate { impl WebSocketEvent for CallCreate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Officially Undocumented; /// Updates the client on which calls are ringing, along with a specific call?; /// @@ -38,7 +38,7 @@ pub struct CallUpdate { impl WebSocketEvent for CallUpdate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Officially Undocumented; /// Deletes a ringing call; /// Ex: {"t":"CALL_DELETE","s":8,"op":0,"d":{"channel_id":"837609115475771392"}} @@ -48,7 +48,7 @@ pub struct CallDelete { impl WebSocketEvent for CallDelete {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Officially Undocumented; /// See ; /// diff --git a/src/types/events/identify.rs b/src/types/events/identify.rs index 4642fb6..70e1721 100644 --- a/src/types/events/identify.rs +++ b/src/types/events/identify.rs @@ -2,7 +2,7 @@ use crate::types::events::{PresenceUpdate, WebSocketEvent}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct GatewayIdentifyPayload { pub token: String, pub properties: GatewayIdentifyConnectionProps, @@ -68,7 +68,7 @@ impl GatewayIdentifyPayload { impl WebSocketEvent for GatewayIdentifyPayload {} -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] #[serde_as] pub struct GatewayIdentifyConnectionProps { /// Almost always sent diff --git a/src/types/events/presence.rs b/src/types/events/presence.rs index c2d985e..d356a2a 100644 --- a/src/types/events/presence.rs +++ b/src/types/events/presence.rs @@ -2,7 +2,7 @@ use crate::types::{events::WebSocketEvent, UserStatus}; use crate::types::{Activity, ClientStatusObject, PublicUser, Snowflake}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Sent by the client to update its status and presence; /// See pub struct UpdatePresence { @@ -14,7 +14,7 @@ pub struct UpdatePresence { pub afk: bool, } -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Received to tell the client that a user updated their presence / status /// See pub struct PresenceUpdate { diff --git a/src/types/events/user.rs b/src/types/events/user.rs index e3ce99a..7165812 100644 --- a/src/types/events/user.rs +++ b/src/types/events/user.rs @@ -4,7 +4,7 @@ use crate::types::entities::PublicUser; use crate::types::events::WebSocketEvent; use crate::types::utils::Snowflake; -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] /// See ; /// Sent to indicate updates to a user object; (name changes, discriminator changes, etc); pub struct UserUpdate { @@ -14,7 +14,7 @@ pub struct UserUpdate { impl WebSocketEvent for UserUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] /// Undocumented; /// /// Possibly an update for muted guild / channel settings for the current user; @@ -39,7 +39,7 @@ pub struct UserGuildSettingsUpdate { impl WebSocketEvent for UserGuildSettingsUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] /// Undocumented; /// /// Received in [UserGuildSettingsUpdate]; diff --git a/src/types/events/webrtc/ready.rs b/src/types/events/webrtc/ready.rs index c805593..4c9aebf 100644 --- a/src/types/events/webrtc/ready.rs +++ b/src/types/events/webrtc/ready.rs @@ -3,7 +3,7 @@ use std::net::Ipv4Addr; use crate::types::WebSocketEvent; use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] /// The ready event for the webrtc stream; /// Used to give info after the identify event; /// See https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-ready-payload; diff --git a/src/types/interfaces/activity.rs b/src/types/interfaces/activity.rs index 1a48dfd..c538731 100644 --- a/src/types/interfaces/activity.rs +++ b/src/types/interfaces/activity.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::Emoji, Snowflake}; -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct Activity { name: String, #[serde(rename = "type")] @@ -22,19 +22,19 @@ pub struct Activity { buttons: Option>, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivityTimestamps { start: Option, end: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivityParty { id: Option, size: Option>, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivityAssets { large_image: Option, large_text: Option, @@ -42,7 +42,7 @@ struct ActivityAssets { small_text: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivitySecrets { join: Option, spectate: Option, @@ -50,7 +50,7 @@ struct ActivitySecrets { match_string: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivityButton { label: String, url: String, From 5f7bab916ec1c5e7fd31e9cde7e2c4e91e247e10 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:53:48 +0200 Subject: [PATCH 205/237] More derives --- src/types/events/webrtc/identify.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/events/webrtc/identify.rs b/src/types/events/webrtc/identify.rs index f41017d..45f1037 100644 --- a/src/types/events/webrtc/identify.rs +++ b/src/types/events/webrtc/identify.rs @@ -1,7 +1,7 @@ use crate::types::{Snowflake, WebSocketEvent}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// The identify payload for the webrtc stream; /// Contains info to begin a webrtc connection; /// See https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-identify-payload; From 7000fad61aa375d4beed6c2e96404d05032ad01f Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:16:45 +0200 Subject: [PATCH 206/237] Even more derives --- src/types/events/hello.rs | 4 ++-- src/types/events/identify.rs | 6 +++--- src/types/events/presence.rs | 4 ++-- src/types/events/voice.rs | 4 ++-- src/types/interfaces/activity.rs | 4 ++-- src/types/interfaces/status.rs | 2 +- src/types/schema/user.rs | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/types/events/hello.rs b/src/types/events/hello.rs index 44f1e4f..fef3e22 100644 --- a/src/types/events/hello.rs +++ b/src/types/events/hello.rs @@ -2,7 +2,7 @@ use crate::types::WebSocketEvent; use serde::{Deserialize, Serialize}; /// Received on gateway init, tells the client how often to send heartbeats; -#[derive(Debug, Default, Deserialize, Serialize)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct GatewayHello { pub op: i32, pub d: HelloData, @@ -10,7 +10,7 @@ pub struct GatewayHello { impl WebSocketEvent for GatewayHello {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq, Copy)] /// Contains info on how often the client should send heartbeats to the server; pub struct HelloData { /// How often a client should send heartbeats, in milliseconds diff --git a/src/types/events/identify.rs b/src/types/events/identify.rs index 70e1721..1353860 100644 --- a/src/types/events/identify.rs +++ b/src/types/events/identify.rs @@ -2,7 +2,7 @@ use crate::types::events::{PresenceUpdate, WebSocketEvent}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Clone)] pub struct GatewayIdentifyPayload { pub token: String, pub properties: GatewayIdentifyConnectionProps, @@ -144,7 +144,7 @@ impl GatewayIdentifyConnectionProps { referring_domain: None, referrer_current: None, release_channel: String::from("stable"), - client_build_number: 199933, + client_build_number: 0, } } @@ -159,7 +159,7 @@ impl GatewayIdentifyConnectionProps { system_locale: String::from("en-US"), os: String::from("Windows"), os_version: Some(String::from("10")), - client_build_number: 199933, + client_build_number: 222963, release_channel: String::from("stable"), ..Self::minimal() } diff --git a/src/types/events/presence.rs b/src/types/events/presence.rs index d356a2a..c2d985e 100644 --- a/src/types/events/presence.rs +++ b/src/types/events/presence.rs @@ -2,7 +2,7 @@ use crate::types::{events::WebSocketEvent, UserStatus}; use crate::types::{Activity, ClientStatusObject, PublicUser, Snowflake}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Default, Clone)] /// Sent by the client to update its status and presence; /// See pub struct UpdatePresence { @@ -14,7 +14,7 @@ pub struct UpdatePresence { pub afk: bool, } -#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Default, Clone)] /// Received to tell the client that a user updated their presence / status /// See pub struct PresenceUpdate { diff --git a/src/types/events/voice.rs b/src/types/events/voice.rs index ff13b73..2618ee1 100644 --- a/src/types/events/voice.rs +++ b/src/types/events/voice.rs @@ -1,7 +1,7 @@ use crate::types::{events::WebSocketEvent, Snowflake, VoiceState}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Default)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)] /// /// Sent to the server to indicate an update of the voice state (leave voice channel, join voice channel, mute, deafen); /// @@ -28,7 +28,7 @@ pub struct VoiceStateUpdate { impl WebSocketEvent for VoiceStateUpdate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// See ; /// /// Received to indicate which voice endpoint, token and guild_id to use; diff --git a/src/types/interfaces/activity.rs b/src/types/interfaces/activity.rs index c538731..23fa406 100644 --- a/src/types/interfaces/activity.rs +++ b/src/types/interfaces/activity.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::Emoji, Snowflake}; -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Clone)] pub struct Activity { name: String, #[serde(rename = "type")] @@ -22,7 +22,7 @@ pub struct Activity { buttons: Option>, } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)] struct ActivityTimestamps { start: Option, end: Option, diff --git a/src/types/interfaces/status.rs b/src/types/interfaces/status.rs index fadaf68..d5c07b6 100644 --- a/src/types/interfaces/status.rs +++ b/src/types/interfaces/status.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// See pub struct ClientStatusObject { pub desktop: Option, diff --git a/src/types/schema/user.rs b/src/types/schema/user.rs index 9946e73..5584cf4 100644 --- a/src/types/schema/user.rs +++ b/src/types/schema/user.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::types::Snowflake; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] #[serde(rename_all = "snake_case")] /// A schema used to modify a user. pub struct UserModifySchema { @@ -29,7 +29,7 @@ pub struct UserModifySchema { /// /// # Reference: /// Read: -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct PrivateChannelCreateSchema { pub recipients: Option>, pub access_tokens: Option>, From dece609d03e406000cf4887846a88bc5001e14bd Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:18:48 +0200 Subject: [PATCH 207/237] Small types update --- src/types/events/webrtc/ready.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/events/webrtc/ready.rs b/src/types/events/webrtc/ready.rs index 4c9aebf..008e41e 100644 --- a/src/types/events/webrtc/ready.rs +++ b/src/types/events/webrtc/ready.rs @@ -8,9 +8,9 @@ use serde::{Deserialize, Serialize}; /// Used to give info after the identify event; /// See https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-ready-payload; pub struct VoiceReady { - ssrc: u8, + ssrc: i32, ip: Ipv4Addr, - port: u8, + port: u32, modes: Vec, // Heartbeat interval is also sent, but is "an erroneous field and should be ignored. The correct heartbeat_interval value comes from the Hello payload." } From 065ff8c9c8c2fa60845372472c3cb22fe0865482 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:25:21 +0200 Subject: [PATCH 208/237] e --- src/types/events/identify.rs | 2 +- src/types/events/presence.rs | 2 +- src/types/interfaces/activity.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types/events/identify.rs b/src/types/events/identify.rs index 1353860..12bc369 100644 --- a/src/types/events/identify.rs +++ b/src/types/events/identify.rs @@ -2,7 +2,7 @@ use crate::types::events::{PresenceUpdate, WebSocketEvent}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct GatewayIdentifyPayload { pub token: String, pub properties: GatewayIdentifyConnectionProps, diff --git a/src/types/events/presence.rs b/src/types/events/presence.rs index c2d985e..e9a7dee 100644 --- a/src/types/events/presence.rs +++ b/src/types/events/presence.rs @@ -14,7 +14,7 @@ pub struct UpdatePresence { pub afk: bool, } -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq)] /// Received to tell the client that a user updated their presence / status /// See pub struct PresenceUpdate { diff --git a/src/types/interfaces/activity.rs b/src/types/interfaces/activity.rs index 23fa406..0da4747 100644 --- a/src/types/interfaces/activity.rs +++ b/src/types/interfaces/activity.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::Emoji, Snowflake}; -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct Activity { name: String, #[serde(rename = "type")] From 141dc32819773a849ab39f6c4ba53fa5084227ea Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:38:26 +0000 Subject: [PATCH 209/237] Error observer (also merge perpetual/gateway-dev) (#425) * Add Webrtc Identify & Ready * Test error observer * Minor updates * More derives * Even more derives * Small types update * e --- src/errors.rs | 7 ++++++- src/gateway.rs | 9 ++++++--- src/types/events/call.rs | 6 +++--- src/types/events/hello.rs | 4 ++-- src/types/events/identify.rs | 8 ++++---- src/types/events/mod.rs | 6 +++++- src/types/events/presence.rs | 2 +- src/types/events/user.rs | 6 +++--- src/types/events/voice.rs | 4 ++-- src/types/events/webrtc/identify.rs | 18 ++++++++++++++++++ src/types/events/webrtc/mod.rs | 5 +++++ src/types/events/webrtc/ready.rs | 29 +++++++++++++++++++++++++++++ src/types/interfaces/activity.rs | 12 ++++++------ src/types/interfaces/status.rs | 2 +- src/types/schema/user.rs | 4 ++-- 15 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 src/types/events/webrtc/identify.rs create mode 100644 src/types/events/webrtc/mod.rs create mode 100644 src/types/events/webrtc/ready.rs diff --git a/src/errors.rs b/src/errors.rs index eebfae3..642a3ba 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -2,6 +2,8 @@ use custom_error::custom_error; use reqwest::Error; +use crate::types::WebSocketEvent; + custom_error! { #[derive(PartialEq, Eq)] pub RegistrationError @@ -54,9 +56,10 @@ custom_error! { /// Supposed to be sent as numbers, though they are sent as string most of the time? /// /// Also includes errors when initiating a connection and unexpected opcodes - #[derive(PartialEq, Eq)] + #[derive(PartialEq, Eq, Default, Clone)] pub GatewayError // Errors we have received from the gateway + #[default] Unknown = "We're not sure what went wrong. Try reconnecting?", UnknownOpcode = "You sent an invalid Gateway opcode or an invalid payload for an opcode", Decode = "Gateway server couldn't decode payload", @@ -79,3 +82,5 @@ custom_error! { // Other misc errors UnexpectedOpcodeReceived{opcode: u8} = "Received an opcode we weren't expecting to receive: {opcode}", } + +impl WebSocketEvent for GatewayError {} diff --git a/src/gateway.rs b/src/gateway.rs index ebe5ca2..e9c6053 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -479,13 +479,15 @@ impl Gateway { return; } - // Todo: handle errors in a good way, maybe observers like events? if msg.is_error() { - warn!("GW: Received error, connection will close.."); + let error = msg.error().unwrap(); - let _error = msg.error(); + warn!("GW: Received error {:?}, connection will close..", error); self.close().await; + + self.events.lock().await.error.notify(error).await; + return; } @@ -935,6 +937,7 @@ mod events { pub webhooks: Webhooks, pub gateway_identify_payload: GatewayEvent, pub gateway_resume: GatewayEvent, + pub error: GatewayEvent, } #[derive(Default, Debug)] diff --git a/src/types/events/call.rs b/src/types/events/call.rs index e37c19d..508aae2 100644 --- a/src/types/events/call.rs +++ b/src/types/events/call.rs @@ -21,7 +21,7 @@ pub struct CallCreate { impl WebSocketEvent for CallCreate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Officially Undocumented; /// Updates the client on which calls are ringing, along with a specific call?; /// @@ -38,7 +38,7 @@ pub struct CallUpdate { impl WebSocketEvent for CallUpdate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Officially Undocumented; /// Deletes a ringing call; /// Ex: {"t":"CALL_DELETE","s":8,"op":0,"d":{"channel_id":"837609115475771392"}} @@ -48,7 +48,7 @@ pub struct CallDelete { impl WebSocketEvent for CallDelete {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// Officially Undocumented; /// See ; /// diff --git a/src/types/events/hello.rs b/src/types/events/hello.rs index 44f1e4f..fef3e22 100644 --- a/src/types/events/hello.rs +++ b/src/types/events/hello.rs @@ -2,7 +2,7 @@ use crate::types::WebSocketEvent; use serde::{Deserialize, Serialize}; /// Received on gateway init, tells the client how often to send heartbeats; -#[derive(Debug, Default, Deserialize, Serialize)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct GatewayHello { pub op: i32, pub d: HelloData, @@ -10,7 +10,7 @@ pub struct GatewayHello { impl WebSocketEvent for GatewayHello {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq, Copy)] /// Contains info on how often the client should send heartbeats to the server; pub struct HelloData { /// How often a client should send heartbeats, in milliseconds diff --git a/src/types/events/identify.rs b/src/types/events/identify.rs index 35e1f78..12bc369 100644 --- a/src/types/events/identify.rs +++ b/src/types/events/identify.rs @@ -2,7 +2,7 @@ use crate::types::events::{PresenceUpdate, WebSocketEvent}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct GatewayIdentifyPayload { pub token: String, pub properties: GatewayIdentifyConnectionProps, @@ -68,7 +68,7 @@ impl GatewayIdentifyPayload { impl WebSocketEvent for GatewayIdentifyPayload {} -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] #[serde_as] pub struct GatewayIdentifyConnectionProps { /// Almost always sent @@ -144,7 +144,7 @@ impl GatewayIdentifyConnectionProps { referring_domain: None, referrer_current: None, release_channel: String::from("stable"), - client_build_number: 199933, + client_build_number: 0, } } @@ -159,7 +159,7 @@ impl GatewayIdentifyConnectionProps { system_locale: String::from("en-US"), os: String::from("Windows"), os_version: Some(String::from("10")), - client_build_number: 199933, + client_build_number: 222963, release_channel: String::from("stable"), ..Self::minimal() } diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index 4f287ce..e440c05 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -5,6 +5,8 @@ use std::collections::HashMap; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; +use serde_json::{from_str, from_value, to_value, Value}; + pub use application::*; pub use auto_moderation::*; pub use call::*; @@ -24,13 +26,13 @@ pub use ready::*; pub use relationship::*; pub use request_members::*; pub use resume::*; -use serde_json::{from_str, from_value, to_value, Value}; pub use session::*; pub use stage_instance::*; pub use thread::*; pub use user::*; pub use voice::*; pub use webhooks::*; +pub use webrtc::*; use crate::gateway::Updateable; @@ -62,6 +64,8 @@ mod user; mod voice; mod webhooks; +mod webrtc; + pub trait WebSocketEvent {} #[derive(Debug, Default, Serialize, Clone)] diff --git a/src/types/events/presence.rs b/src/types/events/presence.rs index c2d985e..e9a7dee 100644 --- a/src/types/events/presence.rs +++ b/src/types/events/presence.rs @@ -14,7 +14,7 @@ pub struct UpdatePresence { pub afk: bool, } -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq)] /// Received to tell the client that a user updated their presence / status /// See pub struct PresenceUpdate { diff --git a/src/types/events/user.rs b/src/types/events/user.rs index e3ce99a..7165812 100644 --- a/src/types/events/user.rs +++ b/src/types/events/user.rs @@ -4,7 +4,7 @@ use crate::types::entities::PublicUser; use crate::types::events::WebSocketEvent; use crate::types::utils::Snowflake; -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] /// See ; /// Sent to indicate updates to a user object; (name changes, discriminator changes, etc); pub struct UserUpdate { @@ -14,7 +14,7 @@ pub struct UserUpdate { impl WebSocketEvent for UserUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] /// Undocumented; /// /// Possibly an update for muted guild / channel settings for the current user; @@ -39,7 +39,7 @@ pub struct UserGuildSettingsUpdate { impl WebSocketEvent for UserGuildSettingsUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)] /// Undocumented; /// /// Received in [UserGuildSettingsUpdate]; diff --git a/src/types/events/voice.rs b/src/types/events/voice.rs index ff13b73..2618ee1 100644 --- a/src/types/events/voice.rs +++ b/src/types/events/voice.rs @@ -1,7 +1,7 @@ use crate::types::{events::WebSocketEvent, Snowflake, VoiceState}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Default)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)] /// /// Sent to the server to indicate an update of the voice state (leave voice channel, join voice channel, mute, deafen); /// @@ -28,7 +28,7 @@ pub struct VoiceStateUpdate { impl WebSocketEvent for VoiceStateUpdate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// See ; /// /// Received to indicate which voice endpoint, token and guild_id to use; diff --git a/src/types/events/webrtc/identify.rs b/src/types/events/webrtc/identify.rs new file mode 100644 index 0000000..45f1037 --- /dev/null +++ b/src/types/events/webrtc/identify.rs @@ -0,0 +1,18 @@ +use crate::types::{Snowflake, WebSocketEvent}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] +/// The identify payload for the webrtc stream; +/// Contains info to begin a webrtc connection; +/// See https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-identify-payload; +pub struct VoiceIdentify { + server_id: Snowflake, + user_id: Snowflake, + session_id: String, + token: String, + #[serde(skip_serializing_if = "Option::is_none")] + /// Undocumented field, but is also in discord client comms + video: Option, +} + +impl WebSocketEvent for VoiceIdentify {} diff --git a/src/types/events/webrtc/mod.rs b/src/types/events/webrtc/mod.rs new file mode 100644 index 0000000..ebaf7b2 --- /dev/null +++ b/src/types/events/webrtc/mod.rs @@ -0,0 +1,5 @@ +pub use identify::*; +pub use ready::*; + +mod identify; +mod ready; diff --git a/src/types/events/webrtc/ready.rs b/src/types/events/webrtc/ready.rs new file mode 100644 index 0000000..008e41e --- /dev/null +++ b/src/types/events/webrtc/ready.rs @@ -0,0 +1,29 @@ +use std::net::Ipv4Addr; + +use crate::types::WebSocketEvent; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +/// The ready event for the webrtc stream; +/// Used to give info after the identify event; +/// See https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-ready-payload; +pub struct VoiceReady { + ssrc: i32, + ip: Ipv4Addr, + port: u32, + modes: Vec, + // Heartbeat interval is also sent, but is "an erroneous field and should be ignored. The correct heartbeat_interval value comes from the Hello payload." +} + +impl Default for VoiceReady { + fn default() -> Self { + VoiceReady { + ssrc: 1, + ip: Ipv4Addr::UNSPECIFIED, + port: 0, + modes: Vec::new(), + } + } +} + +impl WebSocketEvent for VoiceReady {} diff --git a/src/types/interfaces/activity.rs b/src/types/interfaces/activity.rs index 1a48dfd..0da4747 100644 --- a/src/types/interfaces/activity.rs +++ b/src/types/interfaces/activity.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::types::{entities::Emoji, Snowflake}; -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct Activity { name: String, #[serde(rename = "type")] @@ -22,19 +22,19 @@ pub struct Activity { buttons: Option>, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)] struct ActivityTimestamps { start: Option, end: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivityParty { id: Option, size: Option>, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivityAssets { large_image: Option, large_text: Option, @@ -42,7 +42,7 @@ struct ActivityAssets { small_text: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivitySecrets { join: Option, spectate: Option, @@ -50,7 +50,7 @@ struct ActivitySecrets { match_string: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] struct ActivityButton { label: String, url: String, diff --git a/src/types/interfaces/status.rs b/src/types/interfaces/status.rs index fadaf68..d5c07b6 100644 --- a/src/types/interfaces/status.rs +++ b/src/types/interfaces/status.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)] /// See pub struct ClientStatusObject { pub desktop: Option, diff --git a/src/types/schema/user.rs b/src/types/schema/user.rs index 9946e73..5584cf4 100644 --- a/src/types/schema/user.rs +++ b/src/types/schema/user.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::types::Snowflake; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] #[serde(rename_all = "snake_case")] /// A schema used to modify a user. pub struct UserModifySchema { @@ -29,7 +29,7 @@ pub struct UserModifySchema { /// /// # Reference: /// Read: -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct PrivateChannelCreateSchema { pub recipients: Option>, pub access_tokens: Option>, From 0dfd6226619aa63fc328077b54ea6df42b29a325 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Wed, 30 Aug 2023 13:26:19 +0000 Subject: [PATCH 210/237] Fix failing build w/o client and move ratelimits (#426) * Fix failing build without client feature * Feature lock Updateable and Composite --- src/api/auth/login.rs | 3 +-- src/api/auth/register.rs | 2 +- src/api/channels/channels.rs | 5 ++-- src/api/channels/messages.rs | 5 ++-- src/api/channels/permissions.rs | 3 +-- src/api/channels/reactions.rs | 3 +-- src/api/guilds/guilds.rs | 3 +-- src/api/guilds/member.rs | 3 +-- src/api/guilds/roles.rs | 5 ++-- src/api/invites/mod.rs | 8 +++--- src/api/mod.rs | 1 - src/api/policies/instance/mod.rs | 2 -- src/api/policies/mod.rs | 2 -- src/api/users/channels.rs | 3 +-- src/api/users/guilds.rs | 5 ++-- src/api/users/relationships.rs | 4 +-- src/api/users/users.rs | 3 +-- src/instance.rs | 3 +-- src/ratelimiter.rs | 3 +-- .../config/types/subconfigs/limits/rates.rs | 8 +++--- src/types/entities/auto_moderation.rs | 7 +++++- src/types/entities/channel.rs | 24 +++++++++++------- src/types/entities/emoji.rs | 16 +++++++++--- src/types/entities/guild.rs | 25 ++++++++++++------- src/types/entities/mod.rs | 10 ++++++++ .../instance => types/entities}/ratelimits.rs | 0 src/types/entities/role.rs | 16 +++++++++--- src/types/entities/user.rs | 13 +++++++--- src/types/entities/user_settings.rs | 6 +++-- src/types/entities/voice_state.rs | 13 +++++++--- src/types/entities/webhook.rs | 13 +++++++--- src/types/events/auto_moderation.rs | 2 ++ src/types/events/channel.rs | 13 +++++++--- src/types/events/guild.rs | 11 +++++--- src/types/events/mod.rs | 25 +++++++++++++------ src/types/events/thread.rs | 2 ++ 36 files changed, 173 insertions(+), 97 deletions(-) rename src/{api/policies/instance => types/entities}/ratelimits.rs (100%) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index a95c3ca..1564bfb 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -3,12 +3,11 @@ use std::sync::{Arc, RwLock}; use reqwest::Client; use serde_json::to_string; -use crate::api::LimitType; use crate::errors::ChorusResult; use crate::gateway::Gateway; use crate::instance::{ChorusUser, Instance}; use crate::ratelimiter::ChorusRequest; -use crate::types::{GatewayIdentifyPayload, LoginResult, LoginSchema}; +use crate::types::{GatewayIdentifyPayload, LimitType, LoginResult, LoginSchema}; impl Instance { /// Logs into an existing account on the spacebar server. diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 1a95d3d..d278a50 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -6,10 +6,10 @@ use serde_json::to_string; use crate::gateway::Gateway; use crate::types::GatewayIdentifyPayload; use crate::{ - api::policies::instance::LimitType, errors::ChorusResult, instance::{ChorusUser, Instance, Token}, ratelimiter::ChorusRequest, + types::LimitType, types::RegisterSchema, }; diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 7250b0e..9560d74 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -3,11 +3,12 @@ use serde_json::to_string; use crate::types::{AddChannelRecipientSchema, ModifyChannelPositionsSchema}; use crate::{ - api::LimitType, errors::{ChorusError, ChorusResult}, instance::ChorusUser, ratelimiter::ChorusRequest, - types::{Channel, ChannelModifySchema, GetChannelMessagesSchema, Message, Snowflake}, + types::{ + Channel, ChannelModifySchema, GetChannelMessagesSchema, LimitType, Message, Snowflake, + }, }; impl Channel { diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index 960e492..6dfdfbf 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -3,13 +3,12 @@ use http::HeaderMap; use reqwest::{multipart, Client}; use serde_json::{from_value, to_string, Value}; -use crate::api::LimitType; use crate::errors::{ChorusError, ChorusResult}; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, CreateGreetMessage, Message, MessageAck, MessageModifySchema, MessageSearchEndpoint, - MessageSearchQuery, MessageSendSchema, Snowflake, + Channel, CreateGreetMessage, LimitType, Message, MessageAck, MessageModifySchema, + MessageSearchEndpoint, MessageSearchQuery, MessageSendSchema, Snowflake, }; impl Message { diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 7fa8edd..5360890 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -2,11 +2,10 @@ use reqwest::Client; use serde_json::to_string; use crate::{ - api::LimitType, errors::{ChorusError, ChorusResult}, instance::ChorusUser, ratelimiter::ChorusRequest, - types::{self, PermissionOverwrite, Snowflake}, + types::{self, LimitType, PermissionOverwrite, Snowflake}, }; impl types::Channel { diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index 81c0366..94d3087 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -1,9 +1,8 @@ use crate::{ - api::LimitType, errors::ChorusResult, instance::ChorusUser, ratelimiter::ChorusRequest, - types::{self, PublicUser, Snowflake}, + types::{self, LimitType, PublicUser, Snowflake}, }; /// Useful metadata for working with [`types::Reaction`], bundled together nicely. diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 8d5f0d6..b433c84 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -2,14 +2,13 @@ use reqwest::Client; use serde_json::from_str; use serde_json::to_string; -use crate::api::LimitType; use crate::errors::ChorusError; use crate::errors::ChorusResult; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildBansQuery, GuildCreateSchema, - GuildMember, GuildMemberSearchSchema, GuildModifySchema, GuildPreview, + GuildMember, GuildMemberSearchSchema, GuildModifySchema, GuildPreview, LimitType, ModifyGuildMemberProfileSchema, ModifyGuildMemberSchema, UserProfileMetadata, }; use crate::types::{GuildBan, Snowflake}; diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index 01294bd..885ddf9 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -1,11 +1,10 @@ use reqwest::Client; use crate::{ - api::LimitType, errors::ChorusResult, instance::ChorusUser, ratelimiter::ChorusRequest, - types::{self, GuildMember, Snowflake}, + types::{self, GuildMember, LimitType, Snowflake}, }; impl types::GuildMember { diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 17d6f7b..f131367 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -2,11 +2,12 @@ use reqwest::Client; use serde_json::to_string; use crate::{ - api::LimitType, errors::{ChorusError, ChorusResult}, instance::ChorusUser, ratelimiter::ChorusRequest, - types::{self, RoleCreateModifySchema, RoleObject, RolePositionUpdateSchema, Snowflake}, + types::{ + self, LimitType, RoleCreateModifySchema, RoleObject, RolePositionUpdateSchema, Snowflake, + }, }; impl types::RoleObject { diff --git a/src/api/invites/mod.rs b/src/api/invites/mod.rs index 658fb22..332570b 100644 --- a/src/api/invites/mod.rs +++ b/src/api/invites/mod.rs @@ -4,7 +4,7 @@ use serde_json::to_string; use crate::errors::ChorusResult; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; -use crate::types::{CreateChannelInviteSchema, GuildInvite, Invite, Snowflake}; +use crate::types::{CreateChannelInviteSchema, GuildInvite, Invite, LimitType, Snowflake}; impl ChorusUser { /// Accepts an invite to a guild, group DM, or DM. @@ -26,7 +26,7 @@ impl ChorusUser { invite_code )) .header("Authorization", self.token()), - limit_type: super::LimitType::Global, + limit_type: LimitType::Global, }; if session_id.is_some() { request.request = request @@ -53,7 +53,7 @@ impl ChorusUser { .body(to_string(&code).unwrap()) .header("Authorization", self.token()) .header("Content-Type", "application/json"), - limit_type: super::LimitType::Global, + limit_type: LimitType::Global, } .deserialize_response::(self) .await @@ -81,7 +81,7 @@ impl ChorusUser { .header("Authorization", self.token()) .header("Content-Type", "application/json") .body(to_string(&create_channel_invite_schema).unwrap()), - limit_type: super::LimitType::Channel(channel_id), + limit_type: LimitType::Channel(channel_id), } .deserialize_response::(self) .await diff --git a/src/api/mod.rs b/src/api/mod.rs index 7329c50..ab3f9b9 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -3,7 +3,6 @@ pub use channels::messages::*; pub use guilds::*; pub use invites::*; pub use policies::instance::instance::*; -pub use policies::instance::ratelimits::*; pub use users::*; pub mod auth; diff --git a/src/api/policies/instance/mod.rs b/src/api/policies/instance/mod.rs index 0a1f245..b3a9148 100644 --- a/src/api/policies/instance/mod.rs +++ b/src/api/policies/instance/mod.rs @@ -1,5 +1,3 @@ pub use instance::*; -pub use ratelimits::*; pub mod instance; -pub mod ratelimits; diff --git a/src/api/policies/mod.rs b/src/api/policies/mod.rs index d0c29f1..1d5ea99 100644 --- a/src/api/policies/mod.rs +++ b/src/api/policies/mod.rs @@ -1,3 +1 @@ -pub use instance::ratelimits::*; - pub mod instance; diff --git a/src/api/users/channels.rs b/src/api/users/channels.rs index 8d5f063..330b3e3 100644 --- a/src/api/users/channels.rs +++ b/src/api/users/channels.rs @@ -2,11 +2,10 @@ use reqwest::Client; use serde_json::to_string; use crate::{ - api::LimitType, errors::ChorusResult, instance::ChorusUser, ratelimiter::ChorusRequest, - types::{Channel, PrivateChannelCreateSchema}, + types::{Channel, LimitType, PrivateChannelCreateSchema}, }; impl ChorusUser { diff --git a/src/api/users/guilds.rs b/src/api/users/guilds.rs index d2d5b9e..6ffcdfc 100644 --- a/src/api/users/guilds.rs +++ b/src/api/users/guilds.rs @@ -1,11 +1,10 @@ use reqwest::Client; use serde_json::to_string; -use crate::api::LimitType; use crate::errors::ChorusResult; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; -use crate::types::{GetUserGuildSchema, Guild, Snowflake}; +use crate::types::{GetUserGuildSchema, Guild, LimitType, Snowflake}; impl ChorusUser { /// Leaves a given guild. @@ -26,7 +25,7 @@ impl ChorusUser { .header("Authorization", self.token()) .header("Content-Type", "application/json") .body(to_string(&lurking).unwrap()), - limit_type: crate::api::LimitType::Guild(*guild_id), + limit_type: LimitType::Guild(*guild_id), } .handle_request_as_result(self) .await diff --git a/src/api/users/relationships.rs b/src/api/users/relationships.rs index 8988871..4f9602c 100644 --- a/src/api/users/relationships.rs +++ b/src/api/users/relationships.rs @@ -2,12 +2,12 @@ use reqwest::Client; use serde_json::to_string; use crate::{ - api::LimitType, errors::ChorusResult, instance::ChorusUser, ratelimiter::ChorusRequest, types::{ - self, CreateUserRelationshipSchema, FriendRequestSendSchema, RelationshipType, Snowflake, + self, CreateUserRelationshipSchema, FriendRequestSendSchema, LimitType, RelationshipType, + Snowflake, }, }; diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 25ac6cd..0f31d6f 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -4,11 +4,10 @@ use reqwest::Client; use serde_json::to_string; use crate::{ - api::LimitType, errors::{ChorusError, ChorusResult}, instance::{ChorusUser, Instance}, ratelimiter::ChorusRequest, - types::{User, UserModifySchema, UserSettings}, + types::{LimitType, User, UserModifySchema, UserSettings}, }; impl ChorusUser { diff --git a/src/instance.rs b/src/instance.rs index 8ced86a..aa5d4d1 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -8,12 +8,11 @@ use std::sync::{Arc, RwLock}; use reqwest::Client; use serde::{Deserialize, Serialize}; -use crate::api::{Limit, LimitType}; use crate::errors::ChorusResult; use crate::gateway::{Gateway, GatewayHandle}; use crate::ratelimiter::ChorusRequest; use crate::types::types::subconfigs::limits::rates::RateLimits; -use crate::types::{GeneralConfiguration, User, UserSettings}; +use crate::types::{GeneralConfiguration, Limit, LimitType, User, UserSettings}; use crate::UrlBundle; #[derive(Debug, Clone)] diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 84bd641..d20e28a 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -8,10 +8,9 @@ use serde::Deserialize; use serde_json::from_str; use crate::{ - api::{Limit, LimitType}, errors::{ChorusError, ChorusResult}, instance::ChorusUser, - types::{types::subconfigs::limits::rates::RateLimits, LimitsConfiguration}, + types::{types::subconfigs::limits::rates::RateLimits, Limit, LimitType, LimitsConfiguration}, }; /// Chorus' request struct. This struct is used to send rate-limited requests to the Spacebar server. diff --git a/src/types/config/types/subconfigs/limits/rates.rs b/src/types/config/types/subconfigs/limits/rates.rs index ce1ea60..8fdd183 100644 --- a/src/types/config/types/subconfigs/limits/rates.rs +++ b/src/types/config/types/subconfigs/limits/rates.rs @@ -2,11 +2,9 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; -use crate::{ - api::LimitType, - types::config::types::subconfigs::limits::ratelimits::{ - route::RouteRateLimit, RateLimitOptions, - }, +use crate::types::{ + config::types::subconfigs::limits::ratelimits::{route::RouteRateLimit, RateLimitOptions}, + LimitType, }; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] diff --git a/src/types/entities/auto_moderation.rs b/src/types/entities/auto_moderation.rs index eaec2b0..a8910b1 100644 --- a/src/types/entities/auto_moderation.rs +++ b/src/types/entities/auto_moderation.rs @@ -1,13 +1,18 @@ use std::sync::{Arc, RwLock}; +#[cfg(feature = "client")] use crate::gateway::Updateable; + +#[cfg(feature = "client")] use chorus_macros::Updateable; + use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use crate::types::utils::Snowflake; -#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable)] +#[cfg_attr(feature = "client", derive(Updateable))] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] /// See pub struct AutoModerationRule { pub id: Snowflake, diff --git a/src/types/entities/channel.rs b/src/types/entities/channel.rs index 84530c9..280401c 100644 --- a/src/types/entities/channel.rs +++ b/src/types/entities/channel.rs @@ -1,21 +1,28 @@ use std::sync::{Arc, RwLock}; -use chorus_macros::{observe_option_vec, Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_string_from_number; use serde_repr::{Deserialize_repr, Serialize_repr}; use std::fmt::Debug; -use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{GuildMember, User}, utils::Snowflake, - Composite, }; -#[derive(Default, Debug, Serialize, Deserialize, Clone, Updateable, Composite)] +#[cfg(feature = "client")] +use crate::types::Composite; + +#[cfg(feature = "client")] +use crate::gateway::{GatewayHandle, Updateable}; + +#[cfg(feature = "client")] +use chorus_macros::{observe_option_vec, Composite, Updateable}; + +#[derive(Default, Debug, Serialize, Deserialize, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] /// Represents a guild or private channel /// /// # Reference @@ -60,13 +67,13 @@ pub struct Channel { #[cfg(feature = "sqlx")] pub permission_overwrites: Option>>, #[cfg(not(feature = "sqlx"))] - #[observe_option_vec] + #[cfg_attr(feature = "client", observe_option_vec)] pub permission_overwrites: Option>>>, pub permissions: Option, pub position: Option, pub rate_limit_per_user: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - #[observe_option_vec] + #[cfg_attr(feature = "client", observe_option_vec)] pub recipients: Option>>>, pub rtc_region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] @@ -126,9 +133,8 @@ pub struct Tag { pub emoji_name: Option, } -#[derive( - Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Updateable, Composite, -)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd)] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] pub struct PermissionOverwrite { pub id: Snowflake, #[serde(rename = "type")] diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index d80e487..51f78fb 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -1,14 +1,22 @@ use std::fmt::Debug; use std::sync::{Arc, RwLock}; -use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; -use crate::gateway::{GatewayHandle, Updateable}; use crate::types::entities::User; -use crate::types::{Composite, Snowflake}; +use crate::types::Snowflake; -#[derive(Debug, Clone, Deserialize, Serialize, Default, Updateable, Composite)] +#[cfg(feature = "client")] +use crate::types::Composite; + +#[cfg(feature = "client")] +use crate::gateway::{GatewayHandle, Updateable}; + +#[cfg(feature = "client")] +use chorus_macros::{Composite, Updateable}; + +#[derive(Debug, Clone, Deserialize, Serialize, Default)] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// # Reference /// See diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 93b13fc..d810aea 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -1,25 +1,32 @@ use std::fmt::Debug; use std::sync::{Arc, RwLock}; -use chorus_macros::{observe_option_vec, observe_vec, Composite, Updateable}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::gateway::{GatewayHandle, Updateable}; use crate::types::types::guild_configuration::GuildFeaturesList; use crate::types::{ entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook}, interfaces::WelcomeScreenObject, utils::Snowflake, - Composite, }; use bitflags::bitflags; use super::PublicUser; +#[cfg(feature = "client")] +use crate::gateway::{GatewayHandle, Updateable}; + +#[cfg(feature = "client")] +use chorus_macros::{observe_option_vec, observe_vec, Composite, Updateable}; + +#[cfg(feature = "client")] +use crate::types::Composite; + /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Guild { pub afk_channel_id: Option, @@ -34,14 +41,14 @@ pub struct Guild { #[cfg_attr(feature = "sqlx", sqlx(skip))] pub bans: Option>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - #[observe_option_vec] + #[cfg_attr(feature = "client", observe_option_vec)] pub channels: Option>>>, pub default_message_notifications: Option, pub description: Option, pub discovery_splash: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] + #[cfg_attr(feature = "client", observe_vec)] #[serde(default)] - #[observe_vec] pub emojis: Vec>>, pub explicit_content_filter: Option, //#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))] @@ -77,7 +84,7 @@ pub struct Guild { pub public_updates_channel_id: Option, pub region: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - #[observe_option_vec] + #[cfg_attr(feature = "client", observe_option_vec)] pub roles: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub rules_channel: Option, @@ -91,10 +98,10 @@ pub struct Guild { pub vanity_url_code: Option, pub verification_level: Option, #[cfg_attr(feature = "sqlx", sqlx(skip))] - #[observe_option_vec] + #[cfg_attr(feature = "client", observe_option_vec)] pub voice_states: Option>>>, #[cfg_attr(feature = "sqlx", sqlx(skip))] - #[observe_option_vec] + #[cfg_attr(feature = "client", observe_option_vec)] pub webhooks: Option>>>, #[cfg(feature = "sqlx")] pub welcome_screen: Option>, diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index abdf976..a14ef2c 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -10,6 +10,7 @@ pub use guild_member::*; pub use integration::*; pub use invite::*; pub use message::*; +pub use ratelimits::*; pub use relationship::*; pub use role::*; pub use security_key::*; @@ -22,9 +23,16 @@ pub use user_settings::*; pub use voice_state::*; pub use webhook::*; +#[cfg(feature = "client")] use crate::gateway::{GatewayHandle, Updateable}; + +#[cfg(feature = "client")] use async_trait::async_trait; + +#[cfg(feature = "client")] use std::fmt::Debug; + +#[cfg(feature = "client")] use std::sync::{Arc, RwLock}; mod application; @@ -39,6 +47,7 @@ mod guild_member; mod integration; mod invite; mod message; +mod ratelimits; mod relationship; mod role; mod security_key; @@ -51,6 +60,7 @@ mod user_settings; mod voice_state; mod webhook; +#[cfg(feature = "client")] #[async_trait(?Send)] pub trait Composite { async fn watch_whole(self, gateway: &GatewayHandle) -> Self; diff --git a/src/api/policies/instance/ratelimits.rs b/src/types/entities/ratelimits.rs similarity index 100% rename from src/api/policies/instance/ratelimits.rs rename to src/types/entities/ratelimits.rs diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index 22dceff..087a775 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -1,13 +1,21 @@ use bitflags::bitflags; -use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::{deserialize_option_number_from_string, deserialize_string_from_number}; use std::fmt::Debug; -use crate::gateway::{GatewayHandle, Updateable}; -use crate::types::{utils::Snowflake, Composite}; +use crate::types::utils::Snowflake; -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Updateable, Composite)] +#[cfg(feature = "client")] +use chorus_macros::{Composite, Updateable}; + +#[cfg(feature = "client")] +use crate::gateway::{GatewayHandle, Updateable}; + +#[cfg(feature = "client")] +use crate::types::Composite; + +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] /// See pub struct RoleObject { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 64334ff..81d737a 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -1,11 +1,17 @@ -use chorus_macros::{Composite, Updateable}; +use crate::types::utils::Snowflake; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_aux::prelude::deserialize_option_number_from_string; use std::fmt::Debug; +#[cfg(feature = "client")] use crate::gateway::{GatewayHandle, Updateable}; -use crate::types::{utils::Snowflake, Composite}; + +#[cfg(feature = "client")] +use crate::types::Composite; + +#[cfg(feature = "client")] +use chorus_macros::{Composite, Updateable}; use super::Emoji; @@ -21,7 +27,8 @@ impl User { PublicUser::from(self) } } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Updateable, Composite)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct User { pub id: Snowflake, diff --git a/src/types/entities/user_settings.rs b/src/types/entities/user_settings.rs index 1be2c0a..e6db7e7 100644 --- a/src/types/entities/user_settings.rs +++ b/src/types/entities/user_settings.rs @@ -53,15 +53,17 @@ pub struct UserSettings { pub friend_source_flags: sqlx::types::Json, #[cfg(not(feature = "sqlx"))] pub friend_source_flags: FriendSourceFlags, - pub gateway_connected: bool, + pub gateway_connected: Option, pub gif_auto_play: bool, #[cfg(feature = "sqlx")] pub guild_folders: sqlx::types::Json>, #[cfg(not(feature = "sqlx"))] pub guild_folders: Vec, #[cfg(feature = "sqlx")] + #[serde(default)] pub guild_positions: sqlx::types::Json>, #[cfg(not(feature = "sqlx"))] + #[serde(default)] pub guild_positions: Vec, pub inline_attachment_media: bool, pub inline_embed_media: bool, @@ -98,7 +100,7 @@ impl Default for UserSettings { enable_tts_command: false, explicit_content_filter: 0, friend_source_flags: Default::default(), - gateway_connected: false, + gateway_connected: Some(false), gif_auto_play: false, guild_folders: Default::default(), guild_positions: Default::default(), diff --git a/src/types/entities/voice_state.rs b/src/types/entities/voice_state.rs index c879c8e..e764296 100644 --- a/src/types/entities/voice_state.rs +++ b/src/types/entities/voice_state.rs @@ -1,20 +1,27 @@ use std::sync::{Arc, RwLock}; +#[cfg(feature = "client")] use chorus_macros::{Composite, Updateable}; + +#[cfg(feature = "client")] +use crate::types::Composite; + +#[cfg(feature = "client")] +use crate::gateway::{GatewayHandle, Updateable}; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; -use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{ entities::{Guild, GuildMember}, utils::Snowflake, - Composite, }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] pub struct VoiceState { pub guild_id: Option, pub guild: Option, diff --git a/src/types/entities/webhook.rs b/src/types/entities/webhook.rs index 7771dbf..b544ec9 100644 --- a/src/types/entities/webhook.rs +++ b/src/types/entities/webhook.rs @@ -1,18 +1,25 @@ use std::fmt::Debug; use std::sync::{Arc, RwLock}; -use chorus_macros::{Composite, Updateable}; use serde::{Deserialize, Serialize}; +#[cfg(feature = "client")] use crate::gateway::{GatewayHandle, Updateable}; + +#[cfg(feature = "client")] +use chorus_macros::{Composite, Updateable}; + +#[cfg(feature = "client")] +use crate::types::Composite; + use crate::types::{ entities::{Guild, User}, utils::Snowflake, - Composite, }; /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, Updateable, Composite)] +#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[cfg_attr(feature = "client", derive(Updateable, Composite))] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct Webhook { pub id: Snowflake, diff --git a/src/types/events/auto_moderation.rs b/src/types/events/auto_moderation.rs index 376e523..2764ebf 100644 --- a/src/types/events/auto_moderation.rs +++ b/src/types/events/auto_moderation.rs @@ -7,6 +7,7 @@ use crate::types::{ WebSocketEvent, }; +#[cfg(feature = "client")] use super::UpdateMessage; #[derive(Debug, Deserialize, Serialize, Default, Clone)] @@ -27,6 +28,7 @@ pub struct AutoModerationRuleUpdate { pub json: String, } +#[cfg(feature = "client")] impl UpdateMessage for AutoModerationRuleUpdate { fn id(&self) -> Option { Some(self.rule.id) diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index ae84b79..6156c33 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -1,14 +1,18 @@ -use std::sync::{Arc, RwLock}; - use crate::types::events::WebSocketEvent; -use crate::types::Guild; use crate::types::{entities::Channel, JsonField, Snowflake}; use chorus_macros::JsonField; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +#[cfg(feature = "client")] use super::UpdateMessage; +#[cfg(feature = "client")] +use std::sync::{Arc, RwLock}; + +#[cfg(feature = "client")] +use crate::types::Guild; + #[derive(Debug, Default, Deserialize, Serialize)] /// See pub struct ChannelPinsUpdate { @@ -30,6 +34,7 @@ pub struct ChannelCreate { impl WebSocketEvent for ChannelCreate {} +#[cfg(feature = "client")] impl UpdateMessage for ChannelCreate { fn id(&self) -> Option { self.channel.guild_id @@ -57,6 +62,7 @@ pub struct ChannelUpdate { impl WebSocketEvent for ChannelUpdate {} +#[cfg(feature = "client")] impl UpdateMessage for ChannelUpdate { fn update(&mut self, object_to_update: Arc>) { let mut write = object_to_update.write().unwrap(); @@ -96,6 +102,7 @@ pub struct ChannelDelete { pub json: String, } +#[cfg(feature = "client")] impl UpdateMessage for ChannelDelete { fn id(&self) -> Option { self.channel.guild_id diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 0afa9d6..8225961 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -1,5 +1,3 @@ -use std::sync::{Arc, RwLock}; - use chorus_macros::JsonField; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -11,7 +9,12 @@ use crate::types::{ Sticker, }; -use super::{PresenceUpdate, UpdateMessage}; +use super::PresenceUpdate; + +#[cfg(feature = "client")] +use super::UpdateMessage; +#[cfg(feature = "client")] +use std::sync::{Arc, RwLock}; #[derive(Debug, Deserialize, Serialize, Default, Clone)] /// See ; @@ -179,6 +182,7 @@ pub struct GuildRoleCreate { impl WebSocketEvent for GuildRoleCreate {} +#[cfg(feature = "client")] impl UpdateMessage for GuildRoleCreate { fn id(&self) -> Option { Some(self.guild_id) @@ -209,6 +213,7 @@ pub struct GuildRoleUpdate { impl WebSocketEvent for GuildRoleUpdate {} +#[cfg(feature = "client")] impl UpdateMessage for GuildRoleUpdate { fn id(&self) -> Option { Some(self.role.id) diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index e440c05..4e213a1 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -1,12 +1,5 @@ -use std::sync::{Arc, RwLock}; - -use std::collections::HashMap; - -use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; -use serde_json::{from_str, from_value, to_value, Value}; - pub use application::*; pub use auto_moderation::*; pub use call::*; @@ -34,9 +27,23 @@ pub use voice::*; pub use webhooks::*; pub use webrtc::*; +#[cfg(feature = "client")] +use super::Snowflake; + +#[cfg(feature = "client")] use crate::gateway::Updateable; -use super::Snowflake; +#[cfg(feature = "client")] +use serde_json::{from_str, from_value, to_value, Value}; + +#[cfg(feature = "client")] +use std::collections::HashMap; + +#[cfg(feature = "client")] +use std::sync::{Arc, RwLock}; + +#[cfg(feature = "client")] +use serde::de::DeserializeOwned; mod application; mod auto_moderation; @@ -107,6 +114,7 @@ pub struct GatewayReceivePayload<'a> { impl<'a> WebSocketEvent for GatewayReceivePayload<'a> {} +#[cfg(feature = "client")] /// An [`UpdateMessage`] represents a received Gateway Message which contains updated /// information for an [`Updateable`] of Type T. /// # Example: @@ -134,6 +142,7 @@ pub(crate) trait JsonField: Clone { fn get_json(&self) -> String; } +#[cfg(feature = "client")] /// Only applicable for events where the Update struct is the same as the Entity struct pub(crate) fn update_object( value: String, diff --git a/src/types/events/thread.rs b/src/types/events/thread.rs index 19f1cde..5995c19 100644 --- a/src/types/events/thread.rs +++ b/src/types/events/thread.rs @@ -5,6 +5,7 @@ use crate::types::entities::{Channel, ThreadMember}; use crate::types::events::WebSocketEvent; use crate::types::{JsonField, Snowflake}; +#[cfg(feature = "client")] use super::UpdateMessage; #[derive(Debug, Default, Deserialize, Serialize, Clone)] @@ -27,6 +28,7 @@ pub struct ThreadUpdate { impl WebSocketEvent for ThreadUpdate {} +#[cfg(feature = "client")] impl UpdateMessage for ThreadUpdate { fn id(&self) -> Option { Some(self.thread.id) From b949477b245af21f24a36777a6bace2d8146aeb9 Mon Sep 17 00:00:00 2001 From: fowb Date: Wed, 30 Aug 2023 15:29:14 +0200 Subject: [PATCH 211/237] Bump Version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a1e22a..77ed466 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.5.0" +version = "0.6.0" dependencies = [ "async-trait", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index 312d9e9..747acd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.5.0" +version = "0.6.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" From fe8baeb699d2ef721a580bdbf81d15d8644f023d Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 30 Aug 2023 19:13:46 +0200 Subject: [PATCH 212/237] Make UrlBundle `Hash` --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 2edecc2..e63c41d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,7 @@ pub mod types; #[cfg(feature = "client")] pub mod voice; -#[derive(Clone, Default, Debug, PartialEq, Eq)] +#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)] /// A URLBundle bundles together the API-, Gateway- and CDN-URLs of a Spacebar instance. /// /// # Notes From c9c222664d696499b554de3d615638a71fdef8d2 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 00:49:42 +0200 Subject: [PATCH 213/237] Bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77ed466..7c7a258 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.6.0" +version = "0.7.0" dependencies = [ "async-trait", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index 747acd9..629d985 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.6.0" +version = "0.7.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" From a46ffc965c763a163693cd4dc7cff33230f98c76 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 00:49:59 +0200 Subject: [PATCH 214/237] Bump dependencies --- Cargo.lock | 59 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c7a258..9502610 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -220,9 +220,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" dependencies = [ "android-tzdata", "iana-time-zone", @@ -231,7 +231,7 @@ dependencies = [ "serde", "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] @@ -439,9 +439,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -686,21 +686,20 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ "hashbrown 0.14.0", ] [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", + "base64 0.21.3", "bytes", "headers-core", "http", @@ -1033,9 +1032,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" [[package]] name = "mime" @@ -1199,11 +1198,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -1231,9 +1230,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" dependencies = [ "cc", "libc", @@ -1588,9 +1587,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.9" +version = "0.38.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bfe0f2582b4931a45d1fa608f8a8722e8b3c7ac54dd6d5f3b3212791fedef49" +checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" dependencies = [ "bitflags 2.4.0", "errno", @@ -1734,7 +1733,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.27", + "time 0.3.28", ] [[package]] @@ -1799,7 +1798,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.27", + "time 0.3.28", ] [[package]] @@ -2165,9 +2164,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", @@ -2184,9 +2183,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -2447,9 +2446,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", From 9b0567ac9e0bbc04b7632c23ab20457d51636f03 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 00:50:07 +0200 Subject: [PATCH 215/237] Remove borrow --- src/gateway.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gateway.rs b/src/gateway.rs index e9c6053..db26617 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -292,7 +292,7 @@ impl GatewayHandle { /// Sends an update voice state to the server pub async fn send_update_voice_state(&self, to_send: types::UpdateVoiceState) { - let to_send_value = serde_json::to_value(&to_send).unwrap(); + let to_send_value = serde_json::to_value(to_send).unwrap(); trace!("GW: Sending Update Voice State.."); From 42f2f7bfbed373fe4b2bc67edd1f1c514a647942 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 00:50:19 +0200 Subject: [PATCH 216/237] Add Default to LoginSchema --- src/types/schema/auth.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/schema/auth.rs b/src/types/schema/auth.rs index 60e23a4..2159de9 100644 --- a/src/types/schema/auth.rs +++ b/src/types/schema/auth.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub struct RegisterSchema { pub username: String, @@ -15,7 +15,7 @@ pub struct RegisterSchema { pub promotional_email_opt_in: Option, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub struct LoginSchema { /// For Discord, usernames must be between 2 and 32 characters, From 6e136fba832acb0520be5c72a5b49370be89b115 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 01:17:23 +0200 Subject: [PATCH 217/237] Make ChorusError Clone --- src/api/policies/instance/instance.rs | 2 +- src/errors.rs | 4 ++-- src/ratelimiter.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/api/policies/instance/instance.rs b/src/api/policies/instance/instance.rs index aa529ad..4de5fd8 100644 --- a/src/api/policies/instance/instance.rs +++ b/src/api/policies/instance/instance.rs @@ -19,7 +19,7 @@ impl Instance { Err(e) => { return Err(ChorusError::RequestFailed { url: endpoint_url, - error: e, + error: e.to_string(), }); } }; diff --git a/src/errors.rs b/src/errors.rs index 642a3ba..11a7632 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,6 +1,5 @@ //! Contains all the errors that can be returned by the library. use custom_error::custom_error; -use reqwest::Error; use crate::types::WebSocketEvent; @@ -13,11 +12,12 @@ custom_error! { pub type ChorusResult = std::result::Result; custom_error! { + #[derive(Clone)] pub ChorusError /// Server did not respond. NoResponse = "Did not receive a response from the Server.", /// Reqwest returned an Error instead of a Response object. - RequestFailed{url:String, error: Error} = "An error occured while trying to GET from {url}: {error}", + RequestFailed{url:String, error: String} = "An error occured while trying to GET from {url}: {error}", /// Response received, however, it was not of the successful responses type. Used when no other, special case applies. ReceivedErrorCode{error_code: u16, error: String} = "Received the following error code while requesting from the route: {error_code}", /// Used when there is likely something wrong with the instance, the request was directed to. diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index d20e28a..88d4a02 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -91,7 +91,7 @@ impl ChorusRequest { log::warn!("Request failed: {:?}", error); return Err(ChorusError::RequestFailed { url: error.url().unwrap().to_string(), - error, + error: error.to_string(), }); } }; @@ -359,7 +359,7 @@ impl ChorusRequest { Err(e) => { return Err(ChorusError::RequestFailed { url: url_api.to_string(), - error: e, + error: e.to_string(), }) } }; From a8bcb5849328699e8576262e3f9083f8e5a36677 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 12:12:07 +0200 Subject: [PATCH 218/237] Make auth functions take owned values, similar to the rest of the API --- src/api/auth/login.rs | 4 ++-- src/api/auth/register.rs | 4 ++-- tests/auth.rs | 2 +- tests/common/mod.rs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 1564bfb..78826b7 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -14,12 +14,12 @@ impl Instance { /// /// # Reference /// See - pub async fn login_account(&mut self, login_schema: &LoginSchema) -> ChorusResult { + pub async fn login_account(&mut self, login_schema: LoginSchema) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/login"; let chorus_request = ChorusRequest { request: Client::new() .post(endpoint_url) - .body(to_string(login_schema).unwrap()) + .body(to_string(&login_schema).unwrap()) .header("Content-Type", "application/json"), limit_type: LimitType::AuthLogin, }; diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index d278a50..2f1bb28 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -20,13 +20,13 @@ impl Instance { /// See pub async fn register_account( &mut self, - register_schema: &RegisterSchema, + register_schema: RegisterSchema, ) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/register"; let chorus_request = ChorusRequest { request: Client::new() .post(endpoint_url) - .body(to_string(register_schema).unwrap()) + .body(to_string(®ister_schema).unwrap()) .header("Content-Type", "application/json"), limit_type: LimitType::AuthRegister, }; diff --git a/tests/auth.rs b/tests/auth.rs index c26552f..f94f024 100644 --- a/tests/auth.rs +++ b/tests/auth.rs @@ -11,6 +11,6 @@ async fn test_registration() { consent: true, ..Default::default() }; - bundle.instance.register_account(®).await.unwrap(); + bundle.instance.register_account(reg).await.unwrap(); common::teardown(bundle).await; } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index a7b9d5d..e17c354 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -31,7 +31,7 @@ impl TestBundle { ..Default::default() }; self.instance - .register_account(®ister_schema) + .register_account(register_schema) .await .unwrap() } @@ -91,7 +91,7 @@ pub(crate) async fn setup() -> TestBundle { default_thread_rate_limit_per_user: Some(0), video_quality_mode: None, }; - let mut user = instance.register_account(®).await.unwrap(); + let mut user = instance.register_account(reg).await.unwrap(); let guild = Guild::create(&mut user, guild_create_schema).await.unwrap(); let channel = Channel::create(&mut user, guild.id, None, channel_create_schema) .await From e17fcd9e0fb50ad9746a6ec1412903c3cfbf0731 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 13:01:50 +0200 Subject: [PATCH 219/237] Make login only take owned values --- src/api/auth/login.rs | 2 +- src/api/auth/register.rs | 4 ++-- tests/common/mod.rs | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 78826b7..272ee04 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -14,7 +14,7 @@ impl Instance { /// /// # Reference /// See - pub async fn login_account(&mut self, login_schema: LoginSchema) -> ChorusResult { + pub async fn login_account(mut self, login_schema: LoginSchema) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/login"; let chorus_request = ChorusRequest { request: Client::new() diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 2f1bb28..d10915e 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -19,7 +19,7 @@ impl Instance { /// # Reference /// See pub async fn register_account( - &mut self, + mut self, register_schema: RegisterSchema, ) -> ChorusResult { let endpoint_url = self.urls.api.clone() + "/auth/register"; @@ -43,7 +43,7 @@ impl Instance { self.limits_information.as_mut().unwrap().ratelimits = shell.limits.unwrap(); } let user_object = self.get_user(token.clone(), None).await.unwrap(); - let settings = ChorusUser::get_settings(&token, &self.urls.api.clone(), self).await?; + let settings = ChorusUser::get_settings(&token, &self.urls.api.clone(), &mut self).await?; let mut identify = GatewayIdentifyPayload::common(); let gateway = Gateway::new(self.urls.wss.clone()).await.unwrap(); identify.token = token.clone(); diff --git a/tests/common/mod.rs b/tests/common/mod.rs index e17c354..ce42578 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -31,6 +31,7 @@ impl TestBundle { ..Default::default() }; self.instance + .clone() .register_account(register_schema) .await .unwrap() @@ -54,7 +55,7 @@ pub(crate) async fn setup() -> TestBundle { "ws://localhost:3001".to_string(), "http://localhost:3001".to_string(), ); - let mut instance = Instance::new(urls.clone(), true).await.unwrap(); + let instance = Instance::new(urls.clone(), true).await.unwrap(); // Requires the existance of the below user. let reg = RegisterSchema { username: "integrationtestuser".into(), @@ -91,7 +92,7 @@ pub(crate) async fn setup() -> TestBundle { default_thread_rate_limit_per_user: Some(0), video_quality_mode: None, }; - let mut user = instance.register_account(reg).await.unwrap(); + let mut user = instance.clone().register_account(reg).await.unwrap(); let guild = Guild::create(&mut user, guild_create_schema).await.unwrap(); let channel = Channel::create(&mut user, guild.id, None, channel_create_schema) .await From 635361a4174f9cdc17b7b47f69246ff6b28608a9 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 13:02:11 +0200 Subject: [PATCH 220/237] Bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9502610..73fa34e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.7.0" +version = "0.8.0" dependencies = [ "async-trait", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index 629d985..f3d20db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.7.0" +version = "0.8.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" From c6fa385e2822b39f04f55ca34aff1f89271607ac Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 15:02:44 +0200 Subject: [PATCH 221/237] Fix auth --- tests/auth.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auth.rs b/tests/auth.rs index f94f024..f89e5e4 100644 --- a/tests/auth.rs +++ b/tests/auth.rs @@ -4,13 +4,13 @@ mod common; #[tokio::test] async fn test_registration() { - let mut bundle = common::setup().await; + let bundle = common::setup().await; let reg = RegisterSchema { username: "Hiiii".into(), date_of_birth: Some("2000-01-01".to_string()), consent: true, ..Default::default() }; - bundle.instance.register_account(reg).await.unwrap(); + bundle.instance.clone().register_account(reg).await.unwrap(); common::teardown(bundle).await; } From 47ba03102cfbd30b4c03bb8ce3c76fbbe3713805 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 1 Sep 2023 15:02:57 +0200 Subject: [PATCH 222/237] Bugfix time --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73fa34e..6ec87c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.8.0" +version = "0.8.1" dependencies = [ "async-trait", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index f3d20db..9055ee9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.8.0" +version = "0.8.1" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" From bc5e64b79d30a5af75392b5522c56ca7e6f834d7 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:17:49 +0000 Subject: [PATCH 223/237] Add option to login with only a token (#427) * Add login with token --- src/api/auth/mod.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/api/auth/mod.rs b/src/api/auth/mod.rs index 663bf5e..3ad4a60 100644 --- a/src/api/auth/mod.rs +++ b/src/api/auth/mod.rs @@ -1,5 +1,41 @@ +use std::sync::{Arc, RwLock}; + pub use login::*; pub use register::*; +use crate::{ + errors::ChorusResult, + gateway::Gateway, + instance::{ChorusUser, Instance}, + types::{GatewayIdentifyPayload, User}, +}; + pub mod login; pub mod register; + +impl Instance { + /// Logs into an existing account on the spacebar server, using only a token. + pub async fn login_with_token(&mut self, token: String) -> ChorusResult { + let object_result = self.get_user(token.clone(), None).await; + if let Err(e) = object_result { + return Result::Err(e); + } + + let user_settings = User::get_settings(&token, &self.urls.api, &mut self.clone()) + .await + .unwrap(); + let mut identify = GatewayIdentifyPayload::common(); + let gateway = Gateway::new(self.urls.wss.clone()).await.unwrap(); + identify.token = token.clone(); + gateway.send_identify(identify).await; + let user = ChorusUser::new( + Arc::new(RwLock::new(self.clone())), + token.clone(), + self.clone_limits_if_some(), + Arc::new(RwLock::new(user_settings)), + Arc::new(RwLock::new(object_result.unwrap())), + gateway, + ); + Ok(user) + } +} From db533f9700bd0c4ce76cee18cae3b2322e64f2b6 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 3 Sep 2023 16:55:19 +0200 Subject: [PATCH 224/237] Make Errors Hash and Eq, bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/errors.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ec87c6..2a78751 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,7 +177,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chorus" -version = "0.8.1" +version = "0.9.0" dependencies = [ "async-trait", "base64 0.21.3", diff --git a/Cargo.toml b/Cargo.toml index 9055ee9..b8de308 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chorus" description = "A library for interacting with multiple Spacebar-compatible Instances at once." -version = "0.8.1" +version = "0.9.0" license = "AGPL-3.0" edition = "2021" repository = "https://github.com/polyphony-chat/chorus" diff --git a/src/errors.rs b/src/errors.rs index 11a7632..4099a6b 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,7 +4,7 @@ use custom_error::custom_error; use crate::types::WebSocketEvent; custom_error! { - #[derive(PartialEq, Eq)] + #[derive(PartialEq, Eq, Clone, Hash)] pub RegistrationError Consent = "Consent must be 'true' to register.", } @@ -12,7 +12,7 @@ custom_error! { pub type ChorusResult = std::result::Result; custom_error! { - #[derive(Clone)] + #[derive(Clone, Hash, PartialEq, Eq)] pub ChorusError /// Server did not respond. NoResponse = "Did not receive a response from the Server.", From b7ae75f7ce8611dc62377bfb37470b07066fc1f5 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 3 Sep 2023 16:55:34 +0200 Subject: [PATCH 225/237] Add semicolon --- src/gateway.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gateway.rs b/src/gateway.rs index db26617..1eac899 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -499,7 +499,7 @@ impl Gateway { GATEWAY_DISPATCH => { let Some(event_name) = gateway_payload.event_name else { warn!("Gateway dispatch op without event_name"); - return + return; }; trace!("Gateway: Received {event_name}"); From 1340a11a65ed435d7138aee80c504b10dfaa9c38 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 3 Sep 2023 17:09:44 +0200 Subject: [PATCH 226/237] impl Hash for Guild --- src/types/config/types/guild_configuration.rs | 4 +- src/types/entities/emoji.rs | 13 +++ src/types/entities/guild.rs | 91 +++++++++++++++++-- src/types/entities/sticker.rs | 16 ++++ src/types/entities/user.rs | 4 +- src/types/interfaces/guild_welcome_screen.rs | 4 +- 6 files changed, 116 insertions(+), 16 deletions(-) diff --git a/src/types/config/types/guild_configuration.rs b/src/types/config/types/guild_configuration.rs index 96e6ea8..65897ea 100644 --- a/src/types/config/types/guild_configuration.rs +++ b/src/types/config/types/guild_configuration.rs @@ -18,7 +18,7 @@ use crate::types::config::types::subconfigs::guild::{ }; use crate::types::{Error, GuildError}; -#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Hash)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum GuildFeatures { ActivitiesAlpha, @@ -139,7 +139,7 @@ pub enum GuildFeatures { InvitesClosed, } -#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize, Eq)] +#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize, Eq, Hash)] pub struct GuildFeaturesList(Vec); impl Deref for GuildFeaturesList { diff --git a/src/types/entities/emoji.rs b/src/types/entities/emoji.rs index 51f78fb..4f56af5 100644 --- a/src/types/entities/emoji.rs +++ b/src/types/entities/emoji.rs @@ -35,6 +35,19 @@ pub struct Emoji { pub available: Option, } +impl std::hash::Hash for Emoji { + fn hash(&self, state: &mut H) { + self.id.hash(state); + self.name.hash(state); + self.roles.hash(state); + self.roles.hash(state); + self.require_colons.hash(state); + self.managed.hash(state); + self.animated.hash(state); + self.available.hash(state); + } +} + impl PartialEq for Emoji { fn eq(&self, other: &Self) -> bool { !(self.id != other.id diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index d810aea..3739cd2 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -111,8 +111,60 @@ pub struct Guild { pub widget_enabled: Option, } +impl std::hash::Hash for Guild { + fn hash(&self, state: &mut H) { + self.afk_channel_id.hash(state); + self.afk_timeout.hash(state); + self.application_id.hash(state); + self.approximate_member_count.hash(state); + self.approximate_presence_count.hash(state); + self.banner.hash(state); + self.bans.hash(state); + self.default_message_notifications.hash(state); + self.description.hash(state); + self.discovery_splash.hash(state); + self.explicit_content_filter.hash(state); + self.features.hash(state); + self.icon.hash(state); + self.icon_hash.hash(state); + self.id.hash(state); + self.invites.hash(state); + self.joined_at.hash(state); + self.large.hash(state); + self.max_members.hash(state); + self.max_presences.hash(state); + self.max_stage_video_channel_users.hash(state); + self.max_video_channel_users.hash(state); + self.mfa_level.hash(state); + self.name.hash(state); + self.nsfw_level.hash(state); + self.owner.hash(state); + self.owner_id.hash(state); + self.permissions.hash(state); + self.preferred_locale.hash(state); + self.premium_progress_bar_enabled.hash(state); + self.premium_subscription_count.hash(state); + self.premium_tier.hash(state); + self.primary_category_id.hash(state); + self.public_updates_channel_id.hash(state); + self.region.hash(state); + self.rules_channel.hash(state); + self.rules_channel_id.hash(state); + self.splash.hash(state); + self.stickers.hash(state); + self.system_channel_flags.hash(state); + self.system_channel_id.hash(state); + self.vanity_url_code.hash(state); + self.verification_level.hash(state); + self.welcome_screen.hash(state); + self.welcome_screen.hash(state); + self.widget_channel_id.hash(state); + self.widget_enabled.hash(state); + } +} + /// See -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct GuildBan { pub user: PublicUser, @@ -142,7 +194,26 @@ pub struct GuildInvite { pub vanity_url: Option, } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +impl std::hash::Hash for GuildInvite { + fn hash(&self, state: &mut H) { + self.code.hash(state); + self.temporary.hash(state); + self.uses.hash(state); + self.max_uses.hash(state); + self.max_age.hash(state); + self.created_at.hash(state); + self.expires_at.hash(state); + self.guild_id.hash(state); + self.channel_id.hash(state); + self.inviter_id.hash(state); + self.target_user_id.hash(state); + self.target_user.hash(state); + self.target_user_type.hash(state); + self.vanity_url.hash(state); + } +} + +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Hash)] pub struct UnavailableGuild { id: Snowflake, unavailable: bool, @@ -209,7 +280,7 @@ pub struct GuildScheduledEventEntityMetadata { pub location: Option, } -#[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq, Hash)] pub struct VoiceRegion { id: String, name: String, @@ -218,7 +289,7 @@ pub struct VoiceRegion { custom: bool, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq, Hash, Copy)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] /// See @@ -228,7 +299,7 @@ pub enum MessageNotificationLevel { OnlyMentions = 1, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq, Hash, Copy)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] /// See @@ -239,7 +310,7 @@ pub enum ExplicitContentFilterLevel { AllMembers = 2, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq, Hash, Copy)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] /// See @@ -252,7 +323,7 @@ pub enum VerificationLevel { VeryHigh = 4, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq, Hash, Copy)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] /// See @@ -262,7 +333,7 @@ pub enum MFALevel { Elevated = 1, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq, Hash, Copy)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] /// See @@ -274,7 +345,7 @@ pub enum NSFWLevel { AgeRestricted = 3, } -#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq)] +#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, Eq, PartialEq, Hash, Copy)] #[repr(u8)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] /// See @@ -287,7 +358,7 @@ pub enum PremiumTier { } bitflags! { - #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] + #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] /// # Reference /// See pub struct SystemChannelFlags: u64 { diff --git a/src/types/entities/sticker.rs b/src/types/entities/sticker.rs index c2cdb46..593206d 100644 --- a/src/types/entities/sticker.rs +++ b/src/types/entities/sticker.rs @@ -28,6 +28,22 @@ pub struct Sticker { pub sort_value: Option, } +impl std::hash::Hash for Sticker { + fn hash(&self, state: &mut H) { + self.id.hash(state); + self.pack_id.hash(state); + self.name.hash(state); + self.description.hash(state); + self.tags.hash(state); + self.asset.hash(state); + self.sticker_type.hash(state); + self.format_type.hash(state); + self.available.hash(state); + self.guild_id.hash(state); + self.sort_value.hash(state); + } +} + impl PartialEq for Sticker { fn eq(&self, other: &Self) -> bool { self.id == other.id diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index 81d737a..eca5344 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -27,7 +27,7 @@ impl User { PublicUser::from(self) } } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "client", derive(Updateable, Composite))] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct User { @@ -63,7 +63,7 @@ pub struct User { pub disabled: Option, } -#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)] pub struct PublicUser { pub id: Snowflake, pub username: Option, diff --git a/src/types/interfaces/guild_welcome_screen.rs b/src/types/interfaces/guild_welcome_screen.rs index 4912a78..dbeef0f 100644 --- a/src/types/interfaces/guild_welcome_screen.rs +++ b/src/types/interfaces/guild_welcome_screen.rs @@ -2,14 +2,14 @@ use serde::{Deserialize, Serialize}; use crate::types::utils::Snowflake; -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Hash)] pub struct WelcomeScreenObject { pub enabled: bool, pub description: Option, pub welcome_channels: Vec, } -#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Hash)] pub struct WelcomeScreenChannel { pub channel_id: Snowflake, pub description: String, From e6300b3e306166e3a8a3e844b2d14480691cf87c Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 3 Sep 2023 18:29:33 +0200 Subject: [PATCH 227/237] Impl PartialEq, Eq for Guild --- src/types/entities/guild.rs | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index 3739cd2..bdd4998 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -163,6 +163,59 @@ impl std::hash::Hash for Guild { } } +impl std::cmp::PartialEq for Guild { + fn eq(&self, other: &Self) -> bool { + self.afk_channel_id == other.afk_channel_id + && self.afk_timeout == other.afk_timeout + && self.application_id == other.application_id + && self.approximate_member_count == other.approximate_member_count + && self.approximate_presence_count == other.approximate_presence_count + && self.banner == other.banner + && self.bans == other.bans + && self.default_message_notifications == other.default_message_notifications + && self.description == other.description + && self.discovery_splash == other.discovery_splash + && self.explicit_content_filter == other.explicit_content_filter + && self.features == other.features + && self.icon == other.icon + && self.icon_hash == other.icon_hash + && self.id == other.id + && self.joined_at == other.joined_at + && self.large == other.large + && self.max_members == other.max_members + && self.max_presences == other.max_presences + && self.max_stage_video_channel_users == other.max_stage_video_channel_users + && self.max_video_channel_users == other.max_video_channel_users + && self.mfa_level == other.mfa_level + && self.name == other.name + && self.nsfw_level == other.nsfw_level + && self.owner == other.owner + && self.owner_id == other.owner_id + && self.permissions == other.permissions + && self.preferred_locale == other.preferred_locale + && self.premium_progress_bar_enabled == other.premium_progress_bar_enabled + && self.premium_subscription_count == other.premium_subscription_count + && self.premium_tier == other.premium_tier + && self.primary_category_id == other.primary_category_id + && self.public_updates_channel_id == other.public_updates_channel_id + && self.region == other.region + && self.rules_channel == other.rules_channel + && self.rules_channel_id == other.rules_channel_id + && self.splash == other.splash + && self.stickers == other.stickers + && self.system_channel_flags == other.system_channel_flags + && self.system_channel_id == other.system_channel_id + && self.vanity_url_code == other.vanity_url_code + && self.verification_level == other.verification_level + && self.welcome_screen == other.welcome_screen + && self.welcome_screen == other.welcome_screen + && self.widget_channel_id == other.widget_channel_id + && self.widget_enabled == other.widget_enabled + } +} + +impl std::cmp::Eq for Guild {} + /// See #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] From 78b21e9df3729894c857deac8dcb406b57066968 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 3 Sep 2023 19:59:03 +0200 Subject: [PATCH 228/237] Derive Default for Instance --- src/instance.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index aa5d4d1..72bf350 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -15,7 +15,7 @@ use crate::types::types::subconfigs::limits::rates::RateLimits; use crate::types::{GeneralConfiguration, Limit, LimitType, User, UserSettings}; use crate::UrlBundle; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] /// The [`Instance`]; what you will be using to perform all sorts of actions on the Spacebar server. /// If `limits_information` is `None`, then the instance will not be rate limited. pub struct Instance { @@ -25,7 +25,7 @@ pub struct Instance { pub client: Client, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct LimitsInformation { pub ratelimits: HashMap, pub configuration: RateLimits, From c822dc84bbd23b8def302b3f4ac29ee92cdf1957 Mon Sep 17 00:00:00 2001 From: Flori <39242991+bitfl0wer@users.noreply.github.com> Date: Sun, 3 Sep 2023 20:00:23 +0200 Subject: [PATCH 229/237] Update rust-clippy.yml --- .github/workflows/rust-clippy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust-clippy.yml b/.github/workflows/rust-clippy.yml index dbbba76..0c3840f 100644 --- a/.github/workflows/rust-clippy.yml +++ b/.github/workflows/rust-clippy.yml @@ -11,7 +11,7 @@ name: rust-clippy analyze on: push: - branches: [ "main", "preserve/*" ] + branches: [ "main", "preserve/*", "dev" ] pull_request: # The branches below must be a subset of the branches above branches: [ "main" ] From 10b623dbf64fe0316abf586c668e9640eb1df510 Mon Sep 17 00:00:00 2001 From: Flori <39242991+bitfl0wer@users.noreply.github.com> Date: Sun, 3 Sep 2023 20:00:45 +0200 Subject: [PATCH 230/237] Update build_and_test.yml --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 398c52f..b192a3c 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -2,7 +2,7 @@ name: Build and Test on: push: - branches: [ "main" ] + branches: [ "main", "dev" ] pull_request: branches: [ "main" ] From 7938f0295e1695f69e9daa0dcf119401567d95c1 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Sun, 3 Sep 2023 21:00:48 +0200 Subject: [PATCH 231/237] Add source url field trait --- Cargo.lock | 72 +++++++++++++++-------------- Cargo.toml | 2 +- chorus-macros/Cargo.toml | 2 +- chorus-macros/src/lib.rs | 19 ++++++++ src/gateway.rs | 5 +- src/types/events/auto_moderation.rs | 8 ++-- src/types/events/channel.rs | 16 +++++-- src/types/events/guild.rs | 24 ++++++++-- src/types/events/mod.rs | 7 ++- src/types/events/thread.rs | 8 ++-- 10 files changed, 108 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a78751..df89f42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,7 +67,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -211,11 +211,13 @@ dependencies = [ [[package]] name = "chorus-macros" -version = "0.1.0" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a81545a60b926f815517dadbbd40cd502294ae2baea25fa8194d854d607512b0" dependencies = [ "async-trait", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -345,7 +347,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -356,7 +358,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -581,7 +583,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1032,9 +1034,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.2" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "mime" @@ -1183,9 +1185,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -1219,7 +1221,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1310,7 +1312,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1354,9 +1356,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "poem" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d92c532a37a9e98c0e9a0411e6852b8acccf9ec07d5e6e450b01cbf947d90b" +checksum = "ebc7ae19f3e791ae8108b08801abb3708d64d3a16490c720e0b81040cae87b5d" dependencies = [ "async-trait", "bytes", @@ -1383,14 +1385,14 @@ dependencies = [ [[package]] name = "poem-derive" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5dd58846a1f582215370384c3090c62c9ef188e9d798ffc67ea90d0a1a8a3b8" +checksum = "2550a0bce7273b278894ef3ccc5a6869e7031b6870042f3cc6826ed9faa980a6" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1468,9 +1470,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", @@ -1480,9 +1482,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -1682,7 +1684,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1704,7 +1706,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1745,7 +1747,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -2109,9 +2111,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" dependencies = [ "proc-macro2", "quote", @@ -2133,22 +2135,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -2232,7 +2234,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -2337,7 +2339,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -2515,7 +2517,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", "wasm-bindgen-shared", ] @@ -2549,7 +2551,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index b8de308..42a5130 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ thiserror = "1.0.47" jsonwebtoken = "8.3.0" log = "0.4.20" async-trait = "0.1.73" -chorus-macros = { path = "chorus-macros", version = "0.1.0" } +chorus-macros = "0.2.0" [dev-dependencies] tokio = { version = "1.32.0", features = ["full"] } diff --git a/chorus-macros/Cargo.toml b/chorus-macros/Cargo.toml index 098159f..272d99f 100644 --- a/chorus-macros/Cargo.toml +++ b/chorus-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chorus-macros" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "AGPL-3.0" description = "Macros for the chorus crate." diff --git a/chorus-macros/src/lib.rs b/chorus-macros/src/lib.rs index f825568..fd68df0 100644 --- a/chorus-macros/src/lib.rs +++ b/chorus-macros/src/lib.rs @@ -37,6 +37,25 @@ pub fn jsonfield_macro_derive(input: TokenStream) -> TokenStream { .into() } +#[proc_macro_derive(SourceUrlField)] +pub fn source_url_macro_derive(input: TokenStream) -> TokenStream { + let ast: syn::DeriveInput = syn::parse(input).unwrap(); + + let name = &ast.ident; + // No need for macro hygiene, we're only using this in chorus + quote! { + impl SourceUrlField for #name { + fn get_source_url(&self) -> String { + self.source_url.clone() + } + fn set_source_url(&mut self, url: String) { + self.source_url = url; + } + } + } + .into() +} + #[proc_macro_attribute] pub fn observe_option(_args: TokenStream, input: TokenStream) -> TokenStream { input diff --git a/src/gateway.rs b/src/gateway.rs index 1eac899..25072e4 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -5,7 +5,7 @@ use crate::gateway::events::Events; use crate::types::{ self, AutoModerationRule, AutoModerationRuleUpdate, Channel, ChannelCreate, ChannelDelete, ChannelUpdate, Composite, Guild, GuildRoleCreate, GuildRoleUpdate, JsonField, RoleObject, - Snowflake, ThreadUpdate, UpdateMessage, WebSocketEvent, + Snowflake, SourceUrlField, ThreadUpdate, UpdateMessage, WebSocketEvent, }; use async_trait::async_trait; use std::any::Any; @@ -343,6 +343,7 @@ pub struct Gateway { websocket_receive: SplitStream>>, kill_send: tokio::sync::broadcast::Sender<()>, store: Arc>>>>, + url: String, } impl Gateway { @@ -406,6 +407,7 @@ impl Gateway { websocket_receive, kill_send: kill_send.clone(), store: store.clone(), + url: websocket_url.clone(), }; // Now we can continuously check for messages in a different task, since we aren't going to receive another hello @@ -534,6 +536,7 @@ impl Gateway { let downcasted = unsafe { Arc::from_raw(ptr as *const RwLock<$update_type>).clone() }; drop(inner_object); message.set_json(json.to_string()); + message.set_source_url(self.url.clone()); message.update(downcasted.clone()); } else { warn!("Received {} for {}, but it has been observed to be a different type!", $name, id) diff --git a/src/types/events/auto_moderation.rs b/src/types/events/auto_moderation.rs index 2764ebf..2a2eb6b 100644 --- a/src/types/events/auto_moderation.rs +++ b/src/types/events/auto_moderation.rs @@ -1,5 +1,5 @@ -use crate::types::JsonField; -use chorus_macros::JsonField; +use crate::types::{JsonField, SourceUrlField}; +use chorus_macros::{JsonField, SourceUrlField}; use serde::{Deserialize, Serialize}; use crate::types::{ @@ -19,13 +19,15 @@ pub struct AutoModerationRuleCreate { impl WebSocketEvent for AutoModerationRuleCreate {} -#[derive(Debug, Deserialize, Serialize, Default, Clone, JsonField)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, JsonField, SourceUrlField)] /// See pub struct AutoModerationRuleUpdate { #[serde(flatten)] pub rule: AutoModerationRule, #[serde(skip)] pub json: String, + #[serde(skip)] + pub source_url: String, } #[cfg(feature = "client")] diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 6156c33..001be0e 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -1,6 +1,6 @@ use crate::types::events::WebSocketEvent; -use crate::types::{entities::Channel, JsonField, Snowflake}; -use chorus_macros::JsonField; +use crate::types::{entities::Channel, JsonField, Snowflake, SourceUrlField}; +use chorus_macros::{JsonField, SourceUrlField}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -23,13 +23,15 @@ pub struct ChannelPinsUpdate { impl WebSocketEvent for ChannelPinsUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField, SourceUrlField)] /// See pub struct ChannelCreate { #[serde(flatten)] pub channel: Channel, #[serde(skip)] pub json: String, + #[serde(skip)] + pub source_url: String, } impl WebSocketEvent for ChannelCreate {} @@ -51,13 +53,15 @@ impl UpdateMessage for ChannelCreate { } } -#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField, SourceUrlField)] /// See pub struct ChannelUpdate { #[serde(flatten)] pub channel: Channel, #[serde(skip)] pub json: String, + #[serde(skip)] + pub source_url: String, } impl WebSocketEvent for ChannelUpdate {} @@ -93,13 +97,15 @@ pub struct ChannelUnreadUpdateObject { impl WebSocketEvent for ChannelUnreadUpdate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField, SourceUrlField)] /// See pub struct ChannelDelete { #[serde(flatten)] pub channel: Channel, #[serde(skip)] pub json: String, + #[serde(skip)] + pub source_url: String, } #[cfg(feature = "client")] diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index 8225961..b0126c6 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -1,4 +1,4 @@ -use chorus_macros::JsonField; +use chorus_macros::{JsonField, SourceUrlField}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -6,7 +6,7 @@ use crate::types::entities::{Guild, PublicUser, UnavailableGuild}; use crate::types::events::WebSocketEvent; use crate::types::{ AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, JsonField, RoleObject, Snowflake, - Sticker, + SourceUrlField, Sticker, }; use super::PresenceUpdate; @@ -60,16 +60,26 @@ pub struct GuildBanRemove { impl WebSocketEvent for GuildBanRemove {} -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, SourceUrlField, JsonField)] /// See ; /// Received to give info about a guild being updated; pub struct GuildUpdate { #[serde(flatten)] pub guild: Guild, + #[serde(skip)] + pub source_url: String, + #[serde(skip)] + pub json: String, } impl WebSocketEvent for GuildUpdate {} +impl UpdateMessage for GuildUpdate { + fn id(&self) -> Option { + Some(self.guild.id) + } +} + #[derive(Debug, Default, Deserialize, Serialize, Clone)] /// See ; /// Received to tell the client about a guild being deleted; @@ -171,13 +181,15 @@ pub struct GuildMembersChunk { impl WebSocketEvent for GuildMembersChunk {} -#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField, SourceUrlField)] /// See pub struct GuildRoleCreate { pub guild_id: Snowflake, pub role: RoleObject, #[serde(skip)] pub json: String, + #[serde(skip)] + pub source_url: String, } impl WebSocketEvent for GuildRoleCreate {} @@ -202,13 +214,15 @@ impl UpdateMessage for GuildRoleCreate { } } -#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField, SourceUrlField)] /// See pub struct GuildRoleUpdate { pub guild_id: Snowflake, pub role: RoleObject, #[serde(skip)] pub json: String, + #[serde(skip)] + pub source_url: String, } impl WebSocketEvent for GuildRoleUpdate {} diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index 4e213a1..2bca363 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -127,7 +127,7 @@ impl<'a> WebSocketEvent for GatewayReceivePayload<'a> {} /// This would imply, that the [`WebSocketEvent`] "[`ChannelUpdate`]" contains new/updated information /// about a [`Channel`]. The update method describes how this new information will be turned into /// a [`Channel`] object. -pub(crate) trait UpdateMessage: Clone + JsonField +pub(crate) trait UpdateMessage: Clone + JsonField + SourceUrlField where T: Updateable + Serialize + DeserializeOwned + Clone, { @@ -142,6 +142,11 @@ pub(crate) trait JsonField: Clone { fn get_json(&self) -> String; } +pub trait SourceUrlField: Clone { + fn set_source_url(&mut self, url: String); + fn get_source_url(&self) -> String; +} + #[cfg(feature = "client")] /// Only applicable for events where the Update struct is the same as the Entity struct pub(crate) fn update_object( diff --git a/src/types/events/thread.rs b/src/types/events/thread.rs index 5995c19..cff5f6f 100644 --- a/src/types/events/thread.rs +++ b/src/types/events/thread.rs @@ -1,9 +1,9 @@ -use chorus_macros::JsonField; +use chorus_macros::{JsonField, SourceUrlField}; use serde::{Deserialize, Serialize}; use crate::types::entities::{Channel, ThreadMember}; use crate::types::events::WebSocketEvent; -use crate::types::{JsonField, Snowflake}; +use crate::types::{JsonField, Snowflake, SourceUrlField}; #[cfg(feature = "client")] use super::UpdateMessage; @@ -17,13 +17,15 @@ pub struct ThreadCreate { impl WebSocketEvent for ThreadCreate {} -#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonField, SourceUrlField)] /// See pub struct ThreadUpdate { #[serde(flatten)] pub thread: Channel, #[serde(skip)] pub json: String, + #[serde(skip)] + pub source_url: String, } impl WebSocketEvent for ThreadUpdate {} From 242021a50ab59a531750db03ed2af7459c734346 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 5 Sep 2023 13:33:50 +0200 Subject: [PATCH 232/237] Make the fields on this type public --- src/types/entities/guild.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/entities/guild.rs b/src/types/entities/guild.rs index bdd4998..bb4db0c 100644 --- a/src/types/entities/guild.rs +++ b/src/types/entities/guild.rs @@ -268,8 +268,8 @@ impl std::hash::Hash for GuildInvite { #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Hash)] pub struct UnavailableGuild { - id: Snowflake, - unavailable: bool, + pub id: Snowflake, + pub unavailable: bool, } #[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] From 59ab862b17a3c200feaa0590c5c04e7e6d29ade7 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 5 Sep 2023 13:34:22 +0200 Subject: [PATCH 233/237] Simplify this loop --- src/types/events/channel.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/types/events/channel.rs b/src/types/events/channel.rs index 001be0e..eb557d7 100644 --- a/src/types/events/channel.rs +++ b/src/types/events/channel.rs @@ -124,11 +124,7 @@ impl UpdateMessage for ChannelDelete { } for (iteration, item) in (0_u32..).zip(write.channels.as_mut().unwrap().iter()) { if item.read().unwrap().id == self.id().unwrap() { - write - .channels - .as_mut() - .unwrap() - .swap_remove(iteration as usize); + write.channels.as_mut().unwrap().remove(iteration as usize); return; } } From c037c7907bdcca9468ae63924f2832d99f5515f8 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 5 Sep 2023 13:35:01 +0200 Subject: [PATCH 234/237] Implement UpdateMessage for GuildDelete --- src/types/events/guild.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index b0126c6..faf713b 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -80,12 +80,23 @@ impl UpdateMessage for GuildUpdate { } } -#[derive(Debug, Default, Deserialize, Serialize, Clone)] +#[derive(Debug, Default, Deserialize, Serialize, Clone, SourceUrlField, JsonField)] /// See ; /// Received to tell the client about a guild being deleted; pub struct GuildDelete { #[serde(flatten)] pub guild: UnavailableGuild, + #[serde(skip)] + pub source_url: String, + #[serde(skip)] + pub json: String, +} + +impl UpdateMessage for GuildDelete { + fn id(&self) -> Option { + Some(self.guild.id) + } + fn update(&mut self, _: Arc>) {} } impl WebSocketEvent for GuildDelete {} From 3e864602710e6e27d8607fe12dc13e56e0a9abdb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 5 Sep 2023 14:41:02 +0200 Subject: [PATCH 235/237] Implement UpdateMessage for GuildCreate --- src/types/events/guild.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/types/events/guild.rs b/src/types/events/guild.rs index faf713b..0c6bb05 100644 --- a/src/types/events/guild.rs +++ b/src/types/events/guild.rs @@ -16,13 +16,28 @@ use super::UpdateMessage; #[cfg(feature = "client")] use std::sync::{Arc, RwLock}; -#[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[derive(Debug, Deserialize, Serialize, Default, Clone, SourceUrlField, JsonField)] /// See ; /// Received to give data about a guild; // This one is particularly painful, it can be a Guild object with an extra field or an unavailable guild object pub struct GuildCreate { #[serde(flatten)] pub d: GuildCreateDataOption, + #[serde(skip)] + pub source_url: String, + #[serde(skip)] + pub json: String, +} + +impl UpdateMessage for GuildCreate { + fn id(&self) -> Option { + match &self.d { + GuildCreateDataOption::UnavailableGuild(unavailable) => Some(unavailable.id), + GuildCreateDataOption::Guild(guild) => Some(guild.id), + } + } + + fn update(&mut self, _: Arc>) {} } #[derive(Debug, Deserialize, Serialize, Clone)] From 33b99534caeaab6894b88825ede8b01eb803a843 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 5 Sep 2023 22:29:04 +0200 Subject: [PATCH 236/237] Make WebsocketEvent send, Sznc, Debug --- src/types/events/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index 2bca363..f4e926c 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -39,6 +39,7 @@ use serde_json::{from_str, from_value, to_value, Value}; #[cfg(feature = "client")] use std::collections::HashMap; +use std::fmt::Debug; #[cfg(feature = "client")] use std::sync::{Arc, RwLock}; @@ -73,7 +74,7 @@ mod webhooks; mod webrtc; -pub trait WebSocketEvent {} +pub trait WebSocketEvent: Send + Sync + Debug {} #[derive(Debug, Default, Serialize, Clone)] /// The payload used for sending events to the gateway From c4b0891ec8098b627dfd2d73f0b1149aa4f322dc Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Wed, 6 Sep 2023 01:32:38 +0200 Subject: [PATCH 237/237] Make events module pub --- src/gateway.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gateway.rs b/src/gateway.rs index 25072e4..8689406 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -917,7 +917,7 @@ impl GatewayEvent { } } -mod events { +pub mod events { use super::*; #[derive(Default, Debug)]