diff --git a/src/errors/project_create_error.rs b/src/errors/project_create_error.rs index c3dead5..8531ca4 100644 --- a/src/errors/project_create_error.rs +++ b/src/errors/project_create_error.rs @@ -6,12 +6,12 @@ use std::str::FromStr; use validator::{ValidationErrors, ValidationErrorsKind}; #[derive(Serialize, Deserialize, Debug)] -pub enum ProjectCreateError { +pub enum ProjectError { TitleLengthInvalid, Error(Error), } -impl From for ErrorVec { +impl From for ErrorVec { fn from(validation_errors: ValidationErrors) -> Self { validation_errors.errors() .iter() @@ -21,31 +21,31 @@ impl From for ErrorVec { .iter() .map(|validation_error| validation_error.code.as_ref()) .map(|code| match code { - "title_length" => ProjectCreateError::TitleLengthInvalid, + "title_length" => ProjectError::TitleLengthInvalid, _ => panic!("Unexpected validation error code: `{code}`."), }) - .collect::>(), + .collect::>(), _ => panic!("Unexpected validation error kind."), }, _ => panic!("Unexpected validation field name: `{field}`."), }) - .collect::>() + .collect::>() .into() } } // Has to be implemented for Dioxus server functions. -impl Display for ProjectCreateError { +impl Display for ProjectError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self) } } // Has to be implemented for Dioxus server functions. -impl FromStr for ProjectCreateError { +impl FromStr for ProjectError { type Err = (); fn from_str(_: &str) -> Result { - Ok(ProjectCreateError::Error(Error::ServerInternal)) + Ok(ProjectError::Error(Error::ServerInternal)) } } diff --git a/src/server/projects.rs b/src/server/projects.rs index 9644cc8..0d6f623 100644 --- a/src/server/projects.rs +++ b/src/server/projects.rs @@ -1,31 +1,31 @@ use crate::errors::error::Error; use crate::errors::error_vec::ErrorVec; -use crate::errors::project_create_error::ProjectCreateError; +use crate::errors::project_create_error::ProjectError; use crate::models::project::{NewProject, Project}; use crate::server::database_connection::establish_database_connection; -use diesel::{QueryDsl, RunQueryDsl, SelectableHelper}; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl, SelectableHelper}; use dioxus::prelude::*; use validator::Validate; #[server] pub(crate) async fn create_project(new_project: NewProject) - -> Result>> { + -> Result>> { use crate::schema::projects; new_project.validate() - .map_err::, _>(|errors| errors.into())?; + .map_err::, _>(|errors| errors.into())?; let mut connection = establish_database_connection() - .map_err::, _>( - |_| vec![ProjectCreateError::Error(Error::ServerInternal)].into() + .map_err::, _>( + |_| vec![ProjectError::Error(Error::ServerInternal)].into() )?; let new_project = diesel::insert_into(projects::table) .values(&new_project) .returning(Project::as_returning()) .get_result(&mut connection) - .map_err::, _>( - |_| vec![ProjectCreateError::Error(Error::ServerInternal)].into() + .map_err::, _>( + |_| vec![ProjectError::Error(Error::ServerInternal)].into() )?; Ok(new_project) @@ -50,3 +50,28 @@ pub(crate) async fn get_projects() Ok(results) } + +#[server] +pub(crate) async fn edit_project(project_id: i32, new_project: NewProject) + -> Result>> { + use crate::schema::projects::dsl::*; + + new_project.validate() + .map_err::, _>(|errors| errors.into())?; + + let mut connection = establish_database_connection() + .map_err::, _>( + |_| vec![ProjectError::Error(Error::ServerInternal)].into() + )?; + + let updated_project = diesel::update(projects) + .filter(id.eq(project_id)) + .set(title.eq(new_project.title)) + .returning(Project::as_returning()) + .get_result(&mut connection) + .map_err::, _>( + |_| vec![ProjectError::Error(Error::ServerInternal)].into() + )?; + + Ok(updated_project) +}