diff --git a/src/api/schemas.rs b/src/api/schemas.rs index 1fd0e76..e84abdf 100644 --- a/src/api/schemas.rs +++ b/src/api/schemas.rs @@ -299,6 +299,21 @@ pub struct GuildCreateSchema { pub rules_channel_id: Option, } +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub struct UserModifySchema { + pub username: Option, + pub avatar: Option, + pub bio: Option, + pub accent_color: Option, + pub banner: Option, + pub current_password: Option, + pub new_password: Option, + pub code: Option, + pub email: Option, + pub discriminator: Option, +} + // I know that some of these tests are... really really basic and unneccessary, but sometimes, I // just feel like writing tests, so there you go :) -@bitfl0wer #[cfg(test)] diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 88a68ca..7d97734 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -1,13 +1,15 @@ use reqwest::Client; +use serde_json::{from_str, to_string}; use crate::{ api::{ limits::Limits, types::{User, UserObject}, - UserSettings, + UserModifySchema, UserSettings, }, errors::InstanceServerError, instance::Instance, + limit::LimitedRequester, }; impl<'a> User<'a> { @@ -76,6 +78,50 @@ impl<'a> User<'a> { Err(e) => Err(e), } } + + /// Modify the current user's `UserObject`. + /// + /// # Arguments + /// + /// * `modify_schema` - A `UserModifySchema` object containing the fields to modify. + /// + /// # Errors + /// + /// Returns an `InstanceServerError` if the request fails or if a password is required but not provided. + pub async fn modify( + &mut self, + modify_schema: UserModifySchema, + ) -> Result { + if modify_schema.new_password.is_some() + || modify_schema.email.is_some() + || modify_schema.code.is_some() + { + return Err(InstanceServerError::PasswordRequiredError); + } + let request = Client::new() + .patch(format!("{}/users/@me/", self.belongs_to.urls.get_api())) + .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.limits, + &mut self.limits, + ) + .await + { + Ok(response) => response, + Err(e) => return Err(e), + }; + let user_updated: UserObject = from_str(&result.text().await.unwrap()).unwrap(); + let _ = std::mem::replace( + &mut self.object.as_mut().unwrap(), + &mut user_updated.clone(), + ); + Ok(user_updated) + } } impl Instance { diff --git a/src/errors.rs b/src/errors.rs index d449559..f76b029 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -22,6 +22,7 @@ custom_error! { TokenExpired = "Token expired, invalid or not found.", NoPermission = "You do not have the permissions needed to perform this action.", NotFound{error: String} = "The provided resource hasn't been found: {}", + PasswordRequiredError = "You need to provide your current password to authenticate for this action.", } custom_error! {