diff --git a/images/polyphony-chorus-round-light.png b/images/polyphony-chorus-round-light.png deleted file mode 100644 index 000cbf0..0000000 Binary files a/images/polyphony-chorus-round-light.png and /dev/null differ diff --git a/images/polyphony-chorus-round.png b/images/polyphony-chorus-round.png deleted file mode 100644 index 65d8b19..0000000 Binary files a/images/polyphony-chorus-round.png and /dev/null differ diff --git a/images/polyphony-chorus.png b/images/polyphony-chorus.png deleted file mode 100644 index 4587385..0000000 Binary files a/images/polyphony-chorus.png and /dev/null differ diff --git a/images/polyphony-chorus8bit.png b/images/polyphony-chorus8bit.png deleted file mode 100644 index 2d8b987..0000000 Binary files a/images/polyphony-chorus8bit.png and /dev/null differ diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 7ed9fc7..32d9c3a 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -1,44 +1,35 @@ use reqwest::Client; -use serde_json::{from_str, to_string}; +use serde_json::to_string; use crate::{ + api::common, errors::ChorusLibError, instance::UserMeta, - limit::LimitedRequester, types::{Channel, ChannelModifySchema}, }; impl Channel { pub async fn get(user: &mut UserMeta, channel_id: &str) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow_mut(); + let url = belongs_to.urls.get_api().to_string(); + drop(belongs_to); let request = Client::new() - .get(format!( - "{}/channels/{}/", - belongs_to.urls.get_api(), - channel_id - )) + .get(format!("{}/channels/{}/", url, channel_id)) .bearer_auth(user.token()); - let mut requester = 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 result_text = result.text().await.unwrap(); - match from_str::(&result_text) { - Ok(object) => Ok(object), - Err(e) => Err(ChorusLibError::RequestErrorError { - url: format!("{}/channels/{}/", belongs_to.urls.get_api(), channel_id), - error: e.to_string(), - }), + + let result = common::deserialize_response::( + request, + user, + crate::api::limits::LimitType::Channel, + ) + .await; + if result.is_err() { + return Err(ChorusLibError::RequestErrorError { + url: format!("{}/channels/{}/", url, channel_id), + error: result.err().unwrap().to_string(), + }); } + Ok(result.unwrap()) } /// Deletes a channel. @@ -55,7 +46,7 @@ impl Channel { /// /// An `Option` that contains an `ChorusLibError` if an error occurred during the request, or `None` if the request was successful. pub async fn delete(self, user: &mut UserMeta) -> Option { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow_mut(); let request = Client::new() .delete(format!( "{}/channels/{}/", @@ -63,18 +54,13 @@ impl Channel { self.id.to_string() )) .bearer_auth(user.token()); - match LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(_) => None, - Err(e) => return Some(e), + drop(belongs_to); + let response = + common::handle_request(request, user, crate::api::limits::LimitType::Channel).await; + if response.is_err() { + return Some(response.err().unwrap()); + } else { + return None; } } @@ -97,7 +83,7 @@ impl Channel { channel_id: &str, user: &mut UserMeta, ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let request = Client::new() .patch(format!( "{}/channels/{}/", @@ -106,19 +92,14 @@ impl Channel { )) .bearer_auth(user.token()) .body(to_string(&modify_data).unwrap()); - let channel = match LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(channel) => from_str::(&channel.text().await.unwrap()).unwrap(), - Err(e) => return Err(e), - }; + drop(belongs_to); + let channel = common::deserialize_response::( + request, + user, + crate::api::limits::LimitType::Channel, + ) + .await + .unwrap(); Ok(channel) } } diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index d511e24..e15264b 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -3,8 +3,8 @@ use http::HeaderMap; use reqwest::{multipart, Client}; use serde_json::to_string; +use crate::api::deserialize_response; use crate::instance::UserMeta; -use crate::limit::LimitedRequester; use crate::types::{Message, MessageSendSchema, PartialDiscordFileAttachment}; impl Message { @@ -24,23 +24,17 @@ impl Message { channel_id: String, message: &mut MessageSendSchema, files: Option>, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); - let url_api = belongs_to.urls.get_api(); - let mut requester = LimitedRequester::new().await; + ) -> Result { + let belongs_to = user.belongs_to.borrow_mut(); + let url_api = belongs_to.urls.get_api().to_string(); + drop(belongs_to); if files.is_none() { - let message_request = Client::new() + let request = Client::new() .post(format!("{}/channels/{}/messages/", url_api, channel_id)) .bearer_auth(user.token()) .body(to_string(message).unwrap()); - requester - .send_request( - message_request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) + deserialize_response::(request, user, crate::api::limits::LimitType::Channel) .await } else { for (index, attachment) in message.attachments.iter_mut().enumerate() { @@ -70,18 +64,12 @@ impl Message { form = form.part(part_name, part); } - let message_request = Client::new() + let request = Client::new() .post(format!("{}/channels/{}/messages/", url_api, channel_id)) .bearer_auth(user.token()) .multipart(form); - requester - .send_request( - message_request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) + deserialize_response::(request, user, crate::api::limits::LimitType::Channel) .await } } @@ -105,7 +93,7 @@ impl UserMeta { message: &mut MessageSendSchema, channel_id: String, files: Option>, - ) -> Result { + ) -> Result { Message::send(self, channel_id, message, files).await } } diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 0005d15..25c3856 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -2,6 +2,7 @@ use reqwest::Client; use serde_json::to_string; use crate::{ + api::handle_request, errors::ChorusLibError, instance::UserMeta, limit::LimitedRequester, @@ -25,13 +26,14 @@ impl types::Channel { channel_id: &str, overwrite: PermissionOverwrite, ) -> Option { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow_mut(); let url = format!( "{}/channels/{}/permissions/{}", belongs_to.urls.get_api(), channel_id, overwrite.id ); + drop(belongs_to); let body = match to_string(&overwrite) { Ok(string) => string, Err(e) => { @@ -41,17 +43,12 @@ impl types::Channel { } }; let request = Client::new().put(url).bearer_auth(user.token()).body(body); - LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - .unwrap(); - None + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), + } } /// Deletes a permission overwrite for a channel. @@ -70,26 +67,20 @@ impl types::Channel { channel_id: &str, overwrite_id: &str, ) -> Option { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow_mut(); let url = format!( "{}/channels/{}/permissions/{}", belongs_to.urls.get_api(), channel_id, overwrite_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::Channel, - &mut belongs_to.limits, - &mut user.limits, - ) - .await; - if response.is_err() { - return Some(response.err().unwrap()); + match handle_request(request, user, crate::api::limits::LimitType::Channel).await { + Ok(_) => None, + Err(e) => Some(ChorusLibError::InvalidResponseError { + error: e.to_string(), + }), } - None } } diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index e46adba..ea00219 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -1,9 +1,10 @@ use reqwest::Client; use crate::{ + api::{handle_request, handle_request_as_option}, + errors::ChorusLibError, instance::UserMeta, - limit::LimitedRequester, - types::{self}, + types, }; /** @@ -23,33 +24,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 +58,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 +72,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 +93,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 +108,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 +139,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 +148,9 @@ 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 + handle_request_as_option(request, user, crate::api::limits::LimitType::Channel).await } /** @@ -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,9 @@ 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 + handle_request_as_option(request, user, crate::api::limits::LimitType::Channel).await } /** @@ -247,8 +209,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 +219,8 @@ 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 + handle_request_as_option(request, user, crate::api::limits::LimitType::Channel).await } } diff --git a/src/api/common.rs b/src/api/common.rs new file mode 100644 index 0000000..849bf13 --- /dev/null +++ b/src/api/common.rs @@ -0,0 +1,75 @@ +use reqwest::RequestBuilder; +use serde::Deserialize; +use serde_json::from_str; + +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. +pub async fn handle_request( + request: RequestBuilder, + user: &mut UserMeta, + limit_type: LimitType, +) -> Result { + let mut belongs_to = user.belongs_to.borrow_mut(); + match LimitedRequester::new() + .await + .send_request( + request, + limit_type, + &mut belongs_to.limits, + &mut user.limits, + ) + .await + { + Ok(response) => return Ok(response), + Err(e) => return Err(e), + } +} + +/// 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, + limit_type: LimitType, +) -> Result { + let response = handle_request(request, user, limit_type).await.unwrap(); + let response_text = match response.text().await { + Ok(string) => string, + Err(e) => { + return Err(ChorusLibError::InvalidResponseError { + error: format!( + "Error while trying to process the HTTP response into a String: {}", + e.to_string() + ), + }); + } + }; + let object = match from_str::(&response_text) { + Ok(object) => object, + Err(e) => { + return Err(ChorusLibError::InvalidResponseError { + error: format!( + "Error while trying to deserialize the JSON response into T: {}", + e.to_string() + ), + }) + } + }; + Ok(object) +} 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) => { 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 } } diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index f8b3be4..8a94af6 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -2,6 +2,7 @@ use reqwest::Client; use serde_json::{from_str, to_string}; use crate::{ + api::deserialize_response, errors::ChorusLibError, instance::UserMeta, limit::LimitedRequester, @@ -26,36 +27,21 @@ impl types::RoleObject { pub async fn get_all( user: &mut UserMeta, guild_id: &str, - ) -> Result>, crate::errors::ChorusLibError> { - let mut belongs_to = user.belongs_to.borrow_mut(); + ) -> Result>, ChorusLibError> { + let belongs_to = user.belongs_to.borrow(); let url = format!("{}/guilds/{}/roles/", belongs_to.urls.get_api(), guild_id); + drop(belongs_to); let request = Client::new().get(url).bearer_auth(user.token()); - let result = match LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(request) => request, - Err(e) => return Err(e), - }; - let roles: Vec = match from_str(&result.text().await.unwrap()) { - Ok(roles) => roles, - Err(e) => { - return Err(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }); - } - }; - + let roles = deserialize_response::>( + request, + user, + crate::api::limits::LimitType::Guild, + ) + .await + .unwrap(); if roles.is_empty() { return Ok(None); } - Ok(Some(roles)) } @@ -78,38 +64,17 @@ impl types::RoleObject { user: &mut UserMeta, guild_id: &str, role_id: &str, - ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + ) -> Result { + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/guilds/{}/roles/{}/", belongs_to.urls.get_api(), guild_id, role_id ); + drop(belongs_to); let request = Client::new().get(url).bearer_auth(user.token()); - let result = match LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(request) => request, - Err(e) => return Err(e), - }; - let role: RoleObject = match from_str(&result.text().await.unwrap()) { - Ok(role) => role, - Err(e) => { - return Err(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }); - } - }; - - Ok(role) + deserialize_response(request, user, crate::api::limits::LimitType::Guild).await } /// Creates a new role for a given guild. @@ -132,8 +97,9 @@ impl types::RoleObject { guild_id: &str, role_create_schema: RoleCreateModifySchema, ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let url = format!("{}/guilds/{}/roles/", belongs_to.urls.get_api(), guild_id); + drop(belongs_to); let body = match to_string::(&role_create_schema) { Ok(string) => string, Err(e) => { @@ -143,28 +109,7 @@ impl types::RoleObject { } }; let request = Client::new().post(url).bearer_auth(user.token()).body(body); - let result = match LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(request) => request, - Err(e) => return Err(e), - }; - let role: RoleObject = match from_str(&result.text().await.unwrap()) { - Ok(role) => role, - Err(e) => { - return Err(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }); - } - }; - Ok(role) + deserialize_response(request, user, crate::api::limits::LimitType::Guild).await } /// Updates the position of a role in the guild's hierarchy. @@ -187,7 +132,7 @@ impl types::RoleObject { guild_id: &str, role_position_update_schema: types::RolePositionUpdateSchema, ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let url = format!("{}/guilds/{}/roles/", belongs_to.urls.get_api(), guild_id); let body = match to_string(&role_position_update_schema) { Ok(body) => body, @@ -197,29 +142,13 @@ impl types::RoleObject { }); } }; + drop(belongs_to); let request = Client::new() .patch(url) .bearer_auth(user.token()) .body(body); - let response = LimitedRequester::new() + deserialize_response::(request, user, crate::api::limits::LimitType::Guild) .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - .unwrap(); - let role: RoleObject = match from_str(&response.text().await.unwrap()) { - Ok(role) => role, - Err(e) => { - return Err(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }); - } - }; - Ok(role) } /// Updates a role in a guild. @@ -244,13 +173,14 @@ impl types::RoleObject { role_id: &str, role_create_schema: RoleCreateModifySchema, ) -> Result { - let mut belongs_to = user.belongs_to.borrow_mut(); + let belongs_to = user.belongs_to.borrow(); let url = format!( "{}/guilds/{}/roles/{}", belongs_to.urls.get_api(), guild_id, role_id ); + drop(belongs_to); let body = match to_string::(&role_create_schema) { Ok(string) => string, Err(e) => { @@ -263,27 +193,7 @@ impl types::RoleObject { .patch(url) .bearer_auth(user.token()) .body(body); - let result = match LimitedRequester::new() + deserialize_response::(request, user, crate::api::limits::LimitType::Guild) .await - .send_request( - request, - crate::api::limits::LimitType::Guild, - &mut belongs_to.limits, - &mut user.limits, - ) - .await - { - Ok(request) => request, - Err(e) => return Err(e), - }; - let role: RoleObject = match from_str(&result.text().await.unwrap()) { - Ok(role) => role, - Err(e) => { - return Err(ChorusLibError::InvalidResponseError { - error: e.to_string(), - }); - } - }; - Ok(role) } } diff --git a/src/api/mod.rs b/src/api/mod.rs index 850a1b8..56abb5f 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,10 +1,12 @@ pub use channels::messages::*; +pub use common::*; pub use guilds::*; pub use policies::instance::instance::*; pub use policies::instance::limits::*; pub mod auth; pub mod channels; +pub mod common; pub mod guilds; pub mod policies; pub mod users; diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 1d35f32..698fb42 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -2,7 +2,7 @@ use reqwest::Client; use serde_json::{from_str, to_string}; use crate::{ - api::limits::Limits, + api::{deserialize_response, handle_request_as_option, limits::Limits}, errors::ChorusLibError, instance::{Instance, UserMeta}, limit::LimitedRequester, @@ -58,20 +58,10 @@ impl UserMeta { )) .body(to_string(&modify_schema).unwrap()) .bearer_auth(self.token()); - let result = match LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Global, - &mut self.belongs_to.borrow_mut().limits, - &mut self.limits, - ) - .await - { - Ok(response) => response, - Err(e) => return Err(e), - }; - let user_updated: User = from_str(&result.text().await.unwrap()).unwrap(); + let user_updated = + deserialize_response::(request, self, crate::api::limits::LimitType::Ip) + .await + .unwrap(); let _ = std::mem::replace(&mut self.object, user_updated.clone()); Ok(user_updated) } @@ -86,23 +76,12 @@ impl UserMeta { /// /// Returns `None` if the user was successfully deleted, or an `ChorusLibError` if an error occurred. pub async fn delete(mut self) -> Option { - let mut belongs_to = self.belongs_to.borrow_mut(); + let belongs_to = self.belongs_to.borrow(); let request = Client::new() .post(format!("{}/users/@me/delete/", belongs_to.urls.get_api())) - .bearer_auth(self.token); - match LimitedRequester::new() - .await - .send_request( - request, - crate::api::limits::LimitType::Global, - &mut belongs_to.limits, - &mut self.limits, - ) - .await - { - Ok(_) => None, - Err(e) => Some(e), - } + .bearer_auth(self.token()); + drop(belongs_to); + handle_request_as_option(request, &mut self, crate::api::limits::LimitType::Ip).await } } diff --git a/src/types/entities/attachment.rs b/src/types/entities/attachment.rs index 423bac6..7bd9d2b 100644 --- a/src/types/entities/attachment.rs +++ b/src/types/entities/attachment.rs @@ -19,7 +19,7 @@ pub struct Attachment { pub waveform: Option, #[serde(skip_serializing)] #[cfg_attr(feature = "sqlx", sqlx(default))] - pub content: Vec, + pub content: Option>, } #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/src/types/entities/message.rs b/src/types/entities/message.rs index a64ea0d..745d001 100644 --- a/src/types/entities/message.rs +++ b/src/types/entities/message.rs @@ -15,10 +15,10 @@ pub struct Message { pub channel_id: Snowflake, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub author: PublicUser, - pub content: String, + pub content: Option, pub timestamp: String, pub edited_timestamp: Option, - pub tts: bool, + pub tts: Option, pub mention_everyone: bool, #[cfg_attr(feature = "sqlx", sqlx(skip))] pub mentions: Option>,