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
8pub 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}