refactor: custom context for validation

This commit is contained in:
Max Hohlfeld 2025-06-22 21:33:01 +02:00
parent 9666932915
commit b2969b988d
5 changed files with 28 additions and 12 deletions

View File

@ -4,7 +4,7 @@ use sqlx::PgPool;
use crate::{
endpoints::{user::NewOrEditUserForm, IdPath},
models::{Function, Role, User, UserChangeset},
utils::{validation::AsyncValidate, ApplicationError},
utils::{validation::{AsyncValidate, DbContext}, ApplicationError},
};
#[actix_web::post("/users/edit/{id}")]
@ -63,7 +63,8 @@ pub async fn post_edit(
}
}
if let Err(e) = changeset.validate_with_pool(pool.get_ref()).await {
let context = DbContext::new(pool.get_ref());
if let Err(e) = changeset.validate_with_context(&context).await {
return Ok(HttpResponse::UnprocessableEntity().body(e.to_string()));
};

View File

@ -5,7 +5,7 @@ use crate::{
endpoints::user::NewOrEditUserForm,
mail::Mailer,
models::{Function, Registration, Role, User, UserChangeset},
utils::{validation::AsyncValidate, ApplicationError},
utils::{validation::{AsyncValidate, DbContext}, ApplicationError},
};
#[actix_web::post("/users/new")]
@ -57,7 +57,8 @@ pub async fn post_new(
.body("email: an user already exists with the same email"));
}
if let Err(e) = changeset.validate_with_pool(pool.get_ref()).await {
let context = DbContext::new(pool.get_ref());
if let Err(e) = changeset.validate_with_context(&context).await {
return Ok(HttpResponse::UnprocessableEntity().body(e.to_string()));
};

View File

@ -3,7 +3,7 @@ use fake::{faker::internet::en::SafeEmail, faker::name::en::Name, Dummy};
use sqlx::PgPool;
use crate::utils::validation::{email_is_valid, AsyncValidate, AsyncValidateError};
use crate::utils::validation::{email_is_valid, AsyncValidate, AsyncValidateError, DbContext};
use super::{Area, Function, Role};
@ -22,13 +22,15 @@ pub struct UserChangeset {
pub area_id: i32,
}
impl AsyncValidate for UserChangeset {
async fn validate_with_pool(&self, pool: &sqlx::PgPool) -> Result<(), AsyncValidateError> {
impl <'a>AsyncValidate<'a> for UserChangeset {
async fn validate_with_context(&self, context: &'a Self::Context) -> Result<(), AsyncValidateError> {
email_is_valid(&self.email)?;
area_exists(pool, self.area_id).await?;
area_exists(context.pool, self.area_id).await?;
Ok(())
}
type Context = DbContext<'a>;
}
async fn area_exists(pool: &PgPool, id: i32) -> Result<(), AsyncValidateError> {

View File

@ -5,3 +5,14 @@ mod r#trait;
pub use email::email_is_valid;
pub use error::AsyncValidateError;
pub use r#trait::AsyncValidate;
use sqlx::PgPool;
pub struct DbContext<'a> {
pub pool: &'a PgPool,
}
impl<'a> DbContext<'a> {
pub fn new(pool: &'a PgPool) -> Self {
Self { pool }
}
}

View File

@ -1,7 +1,8 @@
use sqlx::PgPool;
use super::AsyncValidateError;
pub trait AsyncValidate {
async fn validate_with_pool(&self, pool: &PgPool) -> Result<(), AsyncValidateError>;
pub trait AsyncValidate<'a> {
type Context: 'a;
async fn validate_with_context(&self, context: &'a Self::Context) -> Result<(), AsyncValidateError>;
}