diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index e59f3bc..0d66686 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -8,8 +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, + Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildBansQuery, GuildCreateSchema, + GuildMember, GuildMemberSearchSchema, GuildModifySchema, GuildPreview, + ModifyGuildMemberProfileSchema, ModifyGuildMemberSchema, UserProfileMetadata, }; use crate::types::{GuildBan, Snowflake}; @@ -145,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) } @@ -295,6 +298,178 @@ 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.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 + } + + /// 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 + } + + /// 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 + } + + /// 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 { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index aadfd35..64334ff 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)] +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 34ced20..56c0f9e 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,58 @@ impl Default for GuildMemberSearchSchema { } } } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +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; + } +} + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct ModifyCurrentGuildMemberSchema { + pub nick: Option, + pub avatar: Option, + 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, +} + +#[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, )