1
0
Fork 0
forked from 2sys/phonograph
phonograph/interim-server/src/extractors.rs

30 lines
955 B
Rust
Raw Normal View History

2025-10-01 22:36:19 -07:00
use axum::extract::{FromRequest, Request};
use axum_extra::extract::Form;
use serde::de::DeserializeOwned;
use validator::Validate;
use crate::errors::{AppError, bad_request};
/// Wrapper around [`axum_extra::extract::Form`] which returns an
/// [`AppError::BadRequest`] if [`validator`] checks on the target type do not
/// pass.
#[derive(Debug, Clone, Copy, Default)]
pub(crate) struct ValidatedForm<T: Validate>(pub(crate) T);
impl<T, S> FromRequest<S> for ValidatedForm<T>
where
T: DeserializeOwned + Validate,
S: Send + Sync,
{
type Rejection = AppError;
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let Form(form) = Form::<T>::from_request(req, state)
.await
.map_err(|err| bad_request!("couldn't parse form: {err}"))?;
form.validate()
.map_err(|err| bad_request!("couldn't validate form: {err}"))?;
Ok(ValidatedForm(form))
}
}