Skip to main content

sova_vld/
ext.rs

1use crate::validate::{read_params_value, read_query_value};
2use crate::ValidationError;
3use sova_core::Request;
4use serde_json::Value;
5use vld::schema::VldParse;
6
7/// Validate request body / query / path params with `vld` `schema!` types.
8pub trait ValidationExt {
9    fn validate<T: VldParse>(
10        &mut self,
11    ) -> impl std::future::Future<Output = Result<T, ValidationError>> + Send;
12
13    fn validate_query<T: VldParse>(&self) -> Result<T, ValidationError>;
14
15    fn validate_params<T: VldParse>(&self) -> Result<T, ValidationError>;
16
17    /// Parse `application/x-www-form-urlencoded` or `multipart/form-data` (feature `form`).
18    #[cfg(feature = "form")]
19    fn validate_form<T: VldParse>(
20        &mut self,
21    ) -> impl std::future::Future<Output = Result<T, ValidationError>> + Send;
22}
23
24impl ValidationExt for Request {
25    async fn validate<T: VldParse>(&mut self) -> Result<T, ValidationError> {
26        let bytes = self.body().await?;
27        let value: Value = serde_json::from_slice(&bytes).map_err(|e| {
28            ValidationError(vld::error::VldError::single(
29                vld::error::IssueCode::ParseError,
30                format!("Invalid JSON: {e}"),
31            ))
32        })?;
33        T::vld_parse_value(&value).map_err(ValidationError::from)
34    }
35
36    fn validate_query<T: VldParse>(&self) -> Result<T, ValidationError> {
37        let value = read_query_value(self);
38        T::vld_parse_value(&value).map_err(ValidationError::from)
39    }
40
41    fn validate_params<T: VldParse>(&self) -> Result<T, ValidationError> {
42        let value = read_params_value(self);
43        T::vld_parse_value(&value).map_err(ValidationError::from)
44    }
45
46    #[cfg(feature = "form")]
47    async fn validate_form<T: VldParse>(&mut self) -> Result<T, ValidationError> {
48        let value = crate::validate::read_form_value(self).await?;
49        T::vld_parse_value(&value).map_err(ValidationError::from)
50    }
51}