From fac9937bdd222fd8aea9897ebb8c42165ccc1a7a Mon Sep 17 00:00:00 2001 From: Flori Weber Date: Sun, 11 Jun 2023 19:13:38 +0200 Subject: [PATCH 1/5] Refactor reactions to use api::options --- src/api/channels/reactions.rs | 151 +++++++++++++--------------------- 1 file changed, 58 insertions(+), 93 deletions(-) diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index e46adba..dc6070b 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -1,10 +1,6 @@ use reqwest::Client; -use crate::{ - instance::UserMeta, - limit::LimitedRequester, - types::{self}, -}; +use crate::{api::handle_request, errors::ChorusLibError, instance::UserMeta, types}; /** Useful metadata for working with [`types::Reaction`], bundled together nicely. @@ -23,33 +19,28 @@ impl ReactionMeta { * `user` - A mutable reference to a [`UserMeta`] instance. # Returns - A `Result` containing a [`reqwest::Response`] or a [`crate::errors::ChorusLibError`]. + An `Option` [`crate::errors::ChorusLibError`] 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) */ - pub async fn delete_all( - &self, - user: &mut UserMeta, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + pub async fn delete_all(&self, user: &mut UserMeta) -> Option { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/channels/{}/messages/{}/reactions/", belongs_to.urls.get_api(), self.channel_id, self.message_id ); + drop(belongs_to); let request = Client::new().delete(url).bearer_auth(user.token()); - LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } } /** @@ -62,17 +53,13 @@ impl ReactionMeta { * `user` - A mutable reference to a [`UserMeta`] instance. # Returns - A `Result` containing a [`reqwest::Response`] or a [`crate::errors::ChorusLibError`]. + A [`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) */ - pub async fn get( - &self, - emoji: &str, - user: &mut UserMeta, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + pub async fn get(&self, emoji: &str, user: &mut UserMeta) -> Option { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/channels/{}/messages/{}/reactions/{}/", belongs_to.urls.get_api(), @@ -80,16 +67,14 @@ impl ReactionMeta { self.message_id, emoji ); + drop(belongs_to); let request = Client::new().get(url).bearer_auth(user.token()); - LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } } /** @@ -103,18 +88,14 @@ impl ReactionMeta { * `user` - A mutable reference to a [`UserMeta`] instance. # Returns - A `Result` containing a [`reqwest::Response`] or a [`crate::errors::ChorusLibError`]. + A [`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) */ - pub async fn delete_emoji( - &self, - emoji: &str, - user: &mut UserMeta, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + pub async fn delete_emoji(&self, emoji: &str, user: &mut UserMeta) -> Option { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/channels/{}/messages/{}/reactions/{}/", belongs_to.urls.get_api(), @@ -122,16 +103,14 @@ impl ReactionMeta { self.message_id, emoji ); + drop(belongs_to); let request = Client::new().delete(url).bearer_auth(user.token()); - LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } } /** @@ -155,12 +134,8 @@ impl ReactionMeta { # Reference See [https://discord.com/developers/docs/resources/channel#create-reaction](https://discord.com/developers/docs/resources/channel#create-reaction) */ - pub async fn create( - &self, - emoji: &str, - user: &mut UserMeta, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + pub async fn create(&self, emoji: &str, user: &mut UserMeta) -> Option { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me/", belongs_to.urls.get_api(), @@ -168,16 +143,14 @@ impl ReactionMeta { self.message_id, emoji ); + drop(belongs_to); let request = Client::new().put(url).bearer_auth(user.token()); - LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } } /** @@ -197,12 +170,8 @@ impl ReactionMeta { # Reference See [https://discord.com/developers/docs/resources/channel#delete-own-reaction](https://discord.com/developers/docs/resources/channel#delete-own-reaction) */ - pub async fn remove( - &self, - emoji: &str, - user: &mut UserMeta, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + pub async fn remove(&self, emoji: &str, user: &mut UserMeta) -> Option { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/channels/{}/messages/{}/reactions/{}/@me/", belongs_to.urls.get_api(), @@ -210,16 +179,14 @@ impl ReactionMeta { self.message_id, emoji ); + drop(belongs_to); let request = Client::new().delete(url).bearer_auth(user.token()); - LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } } /** @@ -247,8 +214,8 @@ impl ReactionMeta { user_id: &str, emoji: &str, user: &mut UserMeta, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + ) -> Option { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/channels/{}/messages/{}/reactions/{}/{}", belongs_to.urls.get_api(), @@ -257,15 +224,13 @@ impl ReactionMeta { emoji, user_id ); + drop(belongs_to); let request = Client::new().delete(url).bearer_auth(user.token()); - LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } } } From 3a8b6c8629c0d422205f78cecaee2dfccdeb7f6a Mon Sep 17 00:00:00 2001 From: Flori Weber Date: Sun, 11 Jun 2023 19:22:10 +0200 Subject: [PATCH 2/5] Introduce handle_request_as_option --- src/api/common.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/api/common.rs b/src/api/common.rs index e20ee89..849bf13 100644 --- a/src/api/common.rs +++ b/src/api/common.rs @@ -6,8 +6,7 @@ use crate::{errors::ChorusLibError, instance::UserMeta, limit::LimitedRequester} use super::limits::LimitType; -/// Sends a request to wherever it needs to go and performs some basic error -/// handling. +/// Sends a request to wherever it needs to go and performs some basic error handling. pub async fn handle_request( request: RequestBuilder, user: &mut UserMeta, @@ -29,6 +28,21 @@ pub async fn handle_request( } } +/// Sends a request to wherever it needs to go. Returns [`None`] on success and +/// [`Some(ChorusLibError)`] on failure. +pub async fn handle_request_as_option( + request: RequestBuilder, + user: &mut UserMeta, + limit_type: LimitType, +) -> Option { + match handle_request(request, user, limit_type).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } +} + pub async fn deserialize_response Deserialize<'a>>( request: RequestBuilder, user: &mut UserMeta, From f6da3dcacfa9585c032961386648b749c9936d2c Mon Sep 17 00:00:00 2001 From: Flori Weber Date: Sun, 11 Jun 2023 19:22:28 +0200 Subject: [PATCH 3/5] Use handle_request_as_option instead --- src/api/channels/reactions.rs | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index dc6070b..ea00219 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -1,6 +1,11 @@ use reqwest::Client; -use crate::{api::handle_request, errors::ChorusLibError, instance::UserMeta, types}; +use crate::{ + api::{handle_request, handle_request_as_option}, + errors::ChorusLibError, + instance::UserMeta, + types, +}; /** Useful metadata for working with [`types::Reaction`], bundled together nicely. @@ -145,12 +150,7 @@ impl ReactionMeta { ); drop(belongs_to); let request = Client::new().put(url).bearer_auth(user.token()); - match handle_request(request, user, crate::api::limits::LimitType::Channel).await { - Ok(_) => None, - Err(e) => Some(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }), - } + handle_request_as_option(request, user, crate::api::limits::LimitType::Channel).await } /** @@ -181,12 +181,7 @@ impl ReactionMeta { ); drop(belongs_to); let request = Client::new().delete(url).bearer_auth(user.token()); - match handle_request(request, user, crate::api::limits::LimitType::Channel).await { - Ok(_) => None, - Err(e) => Some(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }), - } + handle_request_as_option(request, user, crate::api::limits::LimitType::Channel).await } /** @@ -226,11 +221,6 @@ impl ReactionMeta { ); drop(belongs_to); let request = Client::new().delete(url).bearer_auth(user.token()); - match handle_request(request, user, crate::api::limits::LimitType::Channel).await { - Ok(_) => None, - Err(e) => Some(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }), - } + handle_request_as_option(request, user, crate::api::limits::LimitType::Channel).await } } From 3f8724535ee27a6b14435f041497f1a9f3e43c63 Mon Sep 17 00:00:00 2001 From: Flori Weber Date: Sun, 11 Jun 2023 19:26:34 +0200 Subject: [PATCH 4/5] Refactor guilds.rs to use api:common --- src/api/guilds/guilds.rs | 70 +++++++++------------------------------- 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index c94d327..65101e0 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -2,11 +2,14 @@ use reqwest::Client; use serde_json::from_str; use serde_json::to_string; +use crate::api::deserialize_response; +use crate::api::handle_request; +use crate::api::handle_request_as_option; use crate::api::limits::Limits; use crate::errors::ChorusLibError; use crate::instance::UserMeta; use crate::limit::LimitedRequester; -use crate::types::{Channel, ChannelCreateSchema, Guild, GuildCreateResponse, GuildCreateSchema}; +use crate::types::{Channel, ChannelCreateSchema, Guild, GuildCreateSchema}; impl Guild { /// Creates a new guild with the given parameters. @@ -28,37 +31,15 @@ impl Guild { pub async fn create( user: &mut UserMeta, guild_create_schema: GuildCreateSchema, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + ) -> Result { + let belongs_to = user.belongs_to.borrow(); let url = format!("{}/guilds/", belongs_to.urls.get_api()); + drop(belongs_to); let request = reqwest::Client::new() .post(url.clone()) .bearer_auth(user.token.clone()) .body(to_string(&guild_create_schema).unwrap()); - let mut requester = crate::limit::LimitedRequester::new().await; - let result = match requester - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(result) => result, - Err(e) => return Err(e), - }; - let id: GuildCreateResponse = from_str(&result.text().await.unwrap()).unwrap(); - let guild = Guild::_get( - belongs_to.clone().urls.get_api(), - &id.id, - &user.token, - &mut user.limits, - &mut belongs_to.limits, - ) - .await - .unwrap(); - Ok(guild) + deserialize_response::(request, user, crate::api::limits::LimitType::Guild).await } /// Deletes a guild. @@ -86,25 +67,13 @@ impl Guild { /// } /// ``` pub async fn delete(user: &mut UserMeta, guild_id: &str) -> Option { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let url = format!("{}/guilds/{}/delete/", belongs_to.urls.get_api(), guild_id); + drop(belongs_to); let request = reqwest::Client::new() .post(url.clone()) .bearer_auth(user.token.clone()); - let mut requester = crate::limit::LimitedRequester::new().await; - let result = requester - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await; - if result.is_err() { - Some(result.err().unwrap()) - } else { - None - } + handle_request_as_option(request, user, crate::api::limits::LimitType::Guild).await } /// Sends a request to create a new channel in the guild. @@ -147,7 +116,7 @@ impl Guild { /// * `limits_instance` - A mutable reference to a `Limits` struct containing the instance's rate limits. /// pub async fn channels(&self, user: &mut UserMeta) -> Result, ChorusLibError> { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let request = Client::new() .get(format!( "{}/guilds/{}/channels/", @@ -155,19 +124,10 @@ impl Guild { self.id.to_string() )) .bearer_auth(user.token()); - let result = match LimitedRequester::new() + drop(belongs_to); + let result = handle_request(request, user, crate::api::limits::LimitType::Channel) .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(result) => result, - Err(e) => return Err(e), - }; + .unwrap(); let stringed_response = match result.text().await { Ok(value) => value, Err(e) => { From c03c3357fa8afdf176532761ca3bcd6cca9310cd Mon Sep 17 00:00:00 2001 From: Flori Weber Date: Sun, 11 Jun 2023 19:30:15 +0200 Subject: [PATCH 5/5] Refactor member.rs to use api::common --- src/api/guilds/member.rs | 80 +++++++++++----------------------------- 1 file changed, 22 insertions(+), 58 deletions(-) diff --git a/src/api/guilds/member.rs b/src/api/guilds/member.rs index 7b0f5d5..5f09a3c 100644 --- a/src/api/guilds/member.rs +++ b/src/api/guilds/member.rs @@ -1,7 +1,13 @@ use reqwest::Client; use serde_json::from_str; -use crate::{errors::ChorusLibError, instance::UserMeta, limit::LimitedRequester, types}; +use crate::{ + api::{deserialize_response, handle_request_as_option}, + errors::ChorusLibError, + instance::UserMeta, + limit::LimitedRequester, + types, +}; impl types::GuildMember { /// Retrieves a guild member by their ID. @@ -20,39 +26,21 @@ impl types::GuildMember { guild_id: &str, member_id: &str, ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/guilds/{}/members/{}/", belongs_to.urls.get_api(), guild_id, member_id ); + drop(belongs_to); let request = Client::new().get(url).bearer_auth(user.token()); - let response = LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - .unwrap(); - let response_text = match response.text().await { - Ok(string) => string, - Err(e) => { - return Err(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }); - } - }; - let member = from_str::(&response_text); - if member.is_err() { - return Err(ChorusLibError::InvalidResponseError { - error: member.err().unwrap().to_string(), - }); - } - Ok(member.unwrap()) + deserialize_response::( + request, + user, + crate::api::limits::LimitType::Guild, + ) + .await } /// Adds a role to a guild member. @@ -72,8 +60,8 @@ impl types::GuildMember { guild_id: &str, member_id: &str, role_id: &str, - ) -> Option { - let mut belongs_to = user.belongs_to.borrow_mut(); + ) -> Option { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/guilds/{}/members/{}/roles/{}/", belongs_to.urls.get_api(), @@ -81,21 +69,9 @@ impl types::GuildMember { member_id, role_id ); + drop(belongs_to); let request = Client::new().put(url).bearer_auth(user.token()); - let response = LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await; - if response.is_err() { - return Some(response.err().unwrap()); - } else { - return None; - } + handle_request_as_option(request, user, crate::api::limits::LimitType::Guild).await } /// Removes a role from a guild member. @@ -116,7 +92,7 @@ impl types::GuildMember { member_id: &str, role_id: &str, ) -> Option { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/guilds/{}/members/{}/roles/{}/", belongs_to.urls.get_api(), @@ -124,20 +100,8 @@ impl types::GuildMember { member_id, role_id ); + drop(belongs_to); let request = Client::new().delete(url).bearer_auth(user.token()); - let response = LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await; - if response.is_err() { - return Some(response.err().unwrap()); - } else { - return None; - } + handle_request_as_option(request, user, crate::api::limits::LimitType::Guild).await } }