feat: add a server function for editing a project
This commit is contained in:
		| @@ -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<ValidationErrors> for ErrorVec<ProjectCreateError> { | ||||
| impl From<ValidationErrors> for ErrorVec<ProjectError> { | ||||
|     fn from(validation_errors: ValidationErrors) -> Self { | ||||
|         validation_errors.errors() | ||||
|             .iter() | ||||
| @@ -21,31 +21,31 @@ impl From<ValidationErrors> for ErrorVec<ProjectCreateError> { | ||||
|                         .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::<Vec<ProjectCreateError>>(), | ||||
|                         .collect::<Vec<ProjectError>>(), | ||||
|                     _ => panic!("Unexpected validation error kind."), | ||||
|                 }, | ||||
|                 _ => panic!("Unexpected validation field name: `{field}`."), | ||||
|             }) | ||||
|             .collect::<Vec<ProjectCreateError>>() | ||||
|             .collect::<Vec<ProjectError>>() | ||||
|             .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<Self, Self::Err> { | ||||
|         Ok(ProjectCreateError::Error(Error::ServerInternal)) | ||||
|         Ok(ProjectError::Error(Error::ServerInternal)) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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<Project, ServerFnError<ErrorVec<ProjectCreateError>>> { | ||||
|                                    -> Result<Project, ServerFnError<ErrorVec<ProjectError>>> { | ||||
|     use crate::schema::projects; | ||||
|  | ||||
|     new_project.validate() | ||||
|         .map_err::<ErrorVec<ProjectCreateError>, _>(|errors| errors.into())?; | ||||
|         .map_err::<ErrorVec<ProjectError>, _>(|errors| errors.into())?; | ||||
|  | ||||
|     let mut connection = establish_database_connection() | ||||
|         .map_err::<ErrorVec<ProjectCreateError>, _>( | ||||
|             |_| vec![ProjectCreateError::Error(Error::ServerInternal)].into() | ||||
|         .map_err::<ErrorVec<ProjectError>, _>( | ||||
|             |_| 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::<ErrorVec<ProjectCreateError>, _>( | ||||
|             |_| vec![ProjectCreateError::Error(Error::ServerInternal)].into() | ||||
|         .map_err::<ErrorVec<ProjectError>, _>( | ||||
|             |_| 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<Project, ServerFnError<ErrorVec<ProjectError>>> { | ||||
|     use crate::schema::projects::dsl::*; | ||||
|  | ||||
|     new_project.validate() | ||||
|         .map_err::<ErrorVec<ProjectError>, _>(|errors| errors.into())?; | ||||
|  | ||||
|     let mut connection = establish_database_connection() | ||||
|         .map_err::<ErrorVec<ProjectError>, _>( | ||||
|             |_| 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::<ErrorVec<ProjectError>, _>( | ||||
|             |_| vec![ProjectError::Error(Error::ServerInternal)].into() | ||||
|         )?; | ||||
|  | ||||
|     Ok(updated_project) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user