Skip to main content

vld_rama/extract/
path.rs

1use crate::rejection::VldRejection;
2use rama::http::matcher::UriParams;
3use rama::http::request::Parts;
4use rama::http::service::web::extract::FromPartsStateRefPair;
5use vld::schema::VldParse;
6use vld_http_common::coerce_value;
7
8/// Rama extractor that validates **URL path parameters**.
9///
10/// Path segment values are coerced the same way as query parameters.
11pub struct VldPath<T>(pub T);
12
13impl<T, State> FromPartsStateRefPair<State> for VldPath<T>
14where
15    T: VldParse + Send + Sync + 'static,
16    State: Send + Sync + 'static,
17{
18    type Rejection = VldRejection;
19
20    async fn from_parts_state_ref_pair(
21        parts: &Parts,
22        _state: &State,
23    ) -> Result<Self, Self::Rejection> {
24        let params = parts
25            .extensions
26            .get_ref::<UriParams>()
27            .ok_or_else(|| VldRejection::parse("No path parameters found for matched route"))?;
28
29        let mut map = serde_json::Map::new();
30        for (k, v) in params.iter() {
31            map.insert(k.to_string(), coerce_value(v));
32        }
33        let value = serde_json::Value::Object(map);
34
35        let parsed = T::vld_parse_value(&value).map_err(VldRejection::from_vld)?;
36        Ok(VldPath(parsed))
37    }
38}