diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 482a859..a65b36d 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -106,4 +106,59 @@ impl types::RoleObject { }; Ok(role) } + + /// 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 [`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. + pub async fn position_update( + user: &mut UserMeta, + guild_id: &str, + role_position_update_schema: types::RolePositionUpdateSchema, + ) -> Result { + let mut belongs_to = user.belongs_to.borrow_mut(); + let url = format!("{}/guilds/{}/roles/", belongs_to.urls.get_api(), guild_id); + let body = match to_string(&role_position_update_schema) { + Ok(body) => body, + Err(e) => { + return Err(ChorusLibError::FormCreationError { + error: e.to_string(), + }) + } + }; + let request = Client::new() + .patch(url) + .bearer_auth(user.token()) + .body(body); + let response = LimitedRequester::new() + .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) + } } diff --git a/src/types/entities/role.rs b/src/types/entities/role.rs index ba4a2fe..3cbf0ea 100644 --- a/src/types/entities/role.rs +++ b/src/types/entities/role.rs @@ -106,4 +106,30 @@ impl PermissionFlags { pub fn has_permission(&self, permission: PermissionFlags) -> bool { self.contains(permission) || self.contains(PermissionFlags::ADMINISTRATOR) } + + pub fn to_string(&self) -> String { + self.bits().to_string() + } + + /// Creates a String of Permissions from a given [`Vec`] of [`PermissionFlags`]. + /// # Example: + /// ``` + /// use chorus::types::{PermissionFlags}; + /// + /// let mut vector: Vec = Vec::new(); + /// vector.push(PermissionFlags::MUTE_MEMBERS); + /// vector.push(PermissionFlags::DEAFEN_MEMBERS); + /// + /// let permissions: String = PermissionFlags::from_vec(vector); + /// + /// println!("The permissions string is {}.", permissions); + /// assert_eq!(permissions, "12582912".to_string()); + /// ``` + pub fn from_vec(flags: Vec) -> String { + let mut permissions: PermissionFlags = Default::default(); + for flag in flags.iter() { + permissions = permissions | flag.clone(); + } + permissions.to_string() + } } diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index a607123..835f6ad 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -1,4 +1,4 @@ -use crate::types::{entities::Channel, Snowflake}; +use crate::types::entities::Channel; use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize)] @@ -14,27 +14,3 @@ pub struct GuildCreateSchema { pub system_channel_id: Option, pub rules_channel_id: Option, } - -#[derive(Debug, Deserialize, Serialize)] -#[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) -pub struct RoleCreateModifySchema { - pub name: Option, - pub permissions: Option, - pub color: Option, - pub hoist: Option, - pub icon: Option>, - pub unicode_emoji: Option, - pub mentionable: Option, - pub position: Option, -} - -#[derive(Debug, Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -/// Represents the schema which needs to be sent to update a roles' position. -/// See: [https://docs.spacebar.chat/routes/#cmp--schemas-rolepositionupdateschema](https://docs.spacebar.chat/routes/#cmp--schemas-rolepositionupdateschema) -pub struct RolePositionUpdateSchema { - pub id: Snowflake, - pub position: i32, -} diff --git a/src/types/schema/mod.rs b/src/types/schema/mod.rs index 6fe3e37..2e5c4f0 100644 --- a/src/types/schema/mod.rs +++ b/src/types/schema/mod.rs @@ -3,6 +3,7 @@ mod auth; mod channel; mod guild; mod message; +mod role; mod user; pub use apierror::*; @@ -10,6 +11,7 @@ pub use auth::*; pub use channel::*; pub use guild::*; pub use message::*; +pub use role::*; pub use user::*; #[cfg(test)] diff --git a/src/types/schema/role.rs b/src/types/schema/role.rs new file mode 100644 index 0000000..97ab248 --- /dev/null +++ b/src/types/schema/role.rs @@ -0,0 +1,26 @@ +use crate::types::Snowflake; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize)] +#[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) +pub struct RoleCreateModifySchema { + pub name: Option, + pub permissions: Option, + pub color: Option, + pub hoist: Option, + pub icon: Option>, + pub unicode_emoji: Option, + pub mentionable: Option, + pub position: Option, +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +/// Represents the schema which needs to be sent to update a roles' position. +/// See: [https://docs.spacebar.chat/routes/#cmp--schemas-rolepositionupdateschema](https://docs.spacebar.chat/routes/#cmp--schemas-rolepositionupdateschema) +pub struct RolePositionUpdateSchema { + pub id: Snowflake, + pub position: i32, +} diff --git a/tests/roles.rs b/tests/roles.rs index b34bdd7..4a21964 100644 --- a/tests/roles.rs +++ b/tests/roles.rs @@ -5,9 +5,11 @@ use chorus::types::{self, RoleCreateModifySchema}; #[tokio::test] async fn create_and_get_roles() { let mut bundle = common::setup().await; + let permissions = types::PermissionFlags::CONNECT | types::PermissionFlags::MANAGE_EVENTS; + let permissions = Some(permissions.to_string()); let role_create_schema: types::RoleCreateModifySchema = RoleCreateModifySchema { name: Some("cool person".to_string()), - permissions: Some("2251804225".to_string()), + permissions, hoist: Some(true), icon: None, unicode_emoji: Some("".to_string()),