diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 78e32c4..e59f3bc 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -8,7 +8,8 @@ use crate::errors::ChorusResult; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildModifySchema, + Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, + GuildMemberSearchSchema, GuildModifySchema, GuildPreview, }; use crate::types::{GuildBan, Snowflake}; @@ -180,12 +181,120 @@ 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 ChorusUser, + ) -> 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) + } + + /// 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/api/users/guilds.rs b/src/api/users/guilds.rs index 7e0a6c2..5e9b921 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::ChorusUser; use crate::ratelimiter::ChorusRequest; -use crate::types::Snowflake; +use crate::types::{GetUserGuildSchema, Guild, Snowflake}; impl ChorusUser { /// Leaves a given guild. @@ -30,4 +31,28 @@ impl ChorusUser { .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/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 937c439..34ced20 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -3,8 +3,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)] @@ -56,3 +56,53 @@ 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), + } + } +} + +#[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, +} + +#[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), + } + } +}