Skip to main content

ruest/validation/
extract.rs

1use axum::async_trait;
2use axum::extract::{FromRequest, Request};
3use axum::Json;
4use serde::de::DeserializeOwned;
5use validator::Validate;
6
7use super::ValidationError;
8
9/// JSON extractor that runs `validator` automatically.
10pub struct ValidatedJson<T>(pub T);
11
12impl<T> std::ops::Deref for ValidatedJson<T> {
13    type Target = T;
14
15    fn deref(&self) -> &Self::Target {
16        &self.0
17    }
18}
19
20#[async_trait]
21impl<T, S> FromRequest<S> for ValidatedJson<T>
22where
23    T: DeserializeOwned + Validate,
24    S: Send + Sync,
25{
26    type Rejection = ValidationError;
27
28    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
29        let Json(value) = Json::<T>::from_request(req, state)
30            .await
31            .map_err(|_| ValidationError::from_errors(validator::ValidationErrors::new()))?;
32
33        value
34            .validate()
35            .map_err(ValidationError::from_errors)?;
36
37        Ok(ValidatedJson(value))
38    }
39}