raw
1use axum::extract::{FromRequestParts, path::ErrorKind, rejection::PathRejection};
2use http::{StatusCode, request::Parts};
3use serde::de::DeserializeOwned;
4
5use crate::http::{BileState, response::ErrorPage};
6
7pub(crate) struct Path<T>(pub T);
8
9impl<T> FromRequestParts<BileState> for Path<T>
10where
11 T: DeserializeOwned + Send,
12{
13 type Rejection = ErrorPage;
14
15 async fn from_request_parts(
16 parts: &mut Parts,
17 state: &BileState,
18 ) -> Result<Self, Self::Rejection> {
19 match axum::extract::Path::<T>::from_request_parts(parts, state).await {
20 Ok(value) => Ok(Self(value.0)),
21 Err(rejection) => match rejection {
22 PathRejection::FailedToDeserializePathParams(inner) => {
23 let status = match inner.kind() {
24 ErrorKind::UnsupportedType { .. } => StatusCode::INTERNAL_SERVER_ERROR,
25 _ => StatusCode::BAD_REQUEST,
26 };
27
28 Err(ErrorPage::from(state).with_status(status))
29 }
30 _ => Err(ErrorPage::from(state).with_status(StatusCode::INTERNAL_SERVER_ERROR)),
31 },
32 }
33 }
34}
35