mirror of
https://github.com/tokio-rs/axum.git
synced 2024-10-23 17:36:39 +02:00
Implement OptionalFromRequestParts for Path<T>
… and deprecate OptionalPath.
This commit is contained in:
parent
265e65a783
commit
a654c89200
3 changed files with 40 additions and 12 deletions
|
@ -19,7 +19,9 @@ mod query;
|
||||||
#[cfg(feature = "multipart")]
|
#[cfg(feature = "multipart")]
|
||||||
pub mod multipart;
|
pub mod multipart;
|
||||||
|
|
||||||
pub use self::{cached::Cached, optional_path::OptionalPath, with_rejection::WithRejection};
|
#[allow(deprecated)]
|
||||||
|
pub use self::optional_path::OptionalPath;
|
||||||
|
pub use self::{cached::Cached, with_rejection::WithRejection};
|
||||||
|
|
||||||
#[cfg(feature = "cookie")]
|
#[cfg(feature = "cookie")]
|
||||||
pub use self::cookie::CookieJar;
|
pub use self::cookie::CookieJar;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
async_trait,
|
async_trait,
|
||||||
extract::{path::ErrorKind, rejection::PathRejection, FromRequestParts, Path},
|
extract::{rejection::PathRejection, FromRequestParts, Path},
|
||||||
RequestPartsExt,
|
RequestPartsExt,
|
||||||
};
|
};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
@ -32,9 +32,11 @@ use serde::de::DeserializeOwned;
|
||||||
/// .route("/blog/:page", get(render_blog));
|
/// .route("/blog/:page", get(render_blog));
|
||||||
/// # let app: Router = app;
|
/// # let app: Router = app;
|
||||||
/// ```
|
/// ```
|
||||||
|
#[deprecated = "Use Option<Path<_>> instead"]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OptionalPath<T>(pub Option<T>);
|
pub struct OptionalPath<T>(pub Option<T>);
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T, S> FromRequestParts<S> for OptionalPath<T>
|
impl<T, S> FromRequestParts<S> for OptionalPath<T>
|
||||||
where
|
where
|
||||||
|
@ -47,19 +49,15 @@ where
|
||||||
parts: &mut http::request::Parts,
|
parts: &mut http::request::Parts,
|
||||||
_: &S,
|
_: &S,
|
||||||
) -> Result<Self, Self::Rejection> {
|
) -> Result<Self, Self::Rejection> {
|
||||||
match parts.extract::<Path<T>>().await {
|
parts
|
||||||
Ok(Path(params)) => Ok(Self(Some(params))),
|
.extract::<Option<Path<T>>>()
|
||||||
Err(PathRejection::FailedToDeserializePathParams(e))
|
.await
|
||||||
if matches!(e.kind(), ErrorKind::WrongNumberOfParameters { got: 0, .. }) =>
|
.map(|opt| Self(opt.map(|Path(x)| x)))
|
||||||
{
|
|
||||||
Ok(Self(None))
|
|
||||||
}
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[allow(deprecated)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,11 @@ use crate::{
|
||||||
util::PercentDecodedStr,
|
util::PercentDecodedStr,
|
||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use axum_core::response::{IntoResponse, Response};
|
use axum_core::{
|
||||||
|
extract::OptionalFromRequestParts,
|
||||||
|
response::{IntoResponse, Response},
|
||||||
|
RequestPartsExt as _,
|
||||||
|
};
|
||||||
use http::{request::Parts, StatusCode};
|
use http::{request::Parts, StatusCode};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use std::{fmt, sync::Arc};
|
use std::{fmt, sync::Arc};
|
||||||
|
@ -178,6 +182,30 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<T, S> OptionalFromRequestParts<S> for Path<T>
|
||||||
|
where
|
||||||
|
T: DeserializeOwned + Send + 'static,
|
||||||
|
S: Send + Sync,
|
||||||
|
{
|
||||||
|
type Rejection = PathRejection;
|
||||||
|
|
||||||
|
async fn from_request_parts(
|
||||||
|
parts: &mut Parts,
|
||||||
|
_state: &S,
|
||||||
|
) -> Result<Option<Self>, Self::Rejection> {
|
||||||
|
match parts.extract::<Self>().await {
|
||||||
|
Ok(Self(params)) => Ok(Some(Self(params))),
|
||||||
|
Err(PathRejection::FailedToDeserializePathParams(e))
|
||||||
|
if matches!(e.kind(), ErrorKind::WrongNumberOfParameters { got: 0, .. }) =>
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// this wrapper type is used as the deserializer error to hide the `serde::de::Error` impl which
|
// this wrapper type is used as the deserializer error to hide the `serde::de::Error` impl which
|
||||||
// would otherwise be public if we used `ErrorKind` as the error directly
|
// would otherwise be public if we used `ErrorKind` as the error directly
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
Loading…
Reference in a new issue