Skip to content

Commit b8f499e

Browse files
committed
Implement OptionalFromRequestParts for axum-extra's Query<T>
… and deprecate OptionalQuery.
1 parent a654c89 commit b8f499e

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

axum-extra/src/extract/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ pub use self::cookie::SignedCookieJar;
3636
pub use self::form::{Form, FormRejection};
3737

3838
#[cfg(feature = "query")]
39-
pub use self::query::{OptionalQuery, OptionalQueryRejection, Query, QueryRejection};
39+
#[allow(deprecated)]
40+
pub use self::query::OptionalQuery;
41+
#[cfg(feature = "query")]
42+
pub use self::query::{OptionalQueryRejection, Query, QueryRejection};
4043

4144
#[cfg(feature = "multipart")]
4245
pub use self::multipart::Multipart;

axum-extra/src/extract/query.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use axum::{
22
async_trait,
3-
extract::FromRequestParts,
3+
extract::{FromRequestParts, OptionalFromRequestParts},
44
response::{IntoResponse, Response},
55
Error,
66
};
@@ -71,6 +71,28 @@ where
7171
}
7272
}
7373

74+
#[async_trait]
75+
impl<T, S> OptionalFromRequestParts<S> for Query<T>
76+
where
77+
T: DeserializeOwned,
78+
S: Send + Sync,
79+
{
80+
type Rejection = QueryRejection;
81+
82+
async fn from_request_parts(
83+
parts: &mut Parts,
84+
_state: &S,
85+
) -> Result<Option<Self>, Self::Rejection> {
86+
if let Some(query) = parts.uri.query() {
87+
let value = serde_html_form::from_str(query)
88+
.map_err(|err| QueryRejection::FailedToDeserializeQueryString(Error::new(err)))?;
89+
Ok(Some(Self(value)))
90+
} else {
91+
Ok(None)
92+
}
93+
}
94+
}
95+
7496
axum_core::__impl_deref!(Query);
7597

7698
/// Rejection used for [`Query`].
@@ -152,9 +174,11 @@ impl std::error::Error for QueryRejection {
152174
///
153175
/// [example]: https://github.com/tokio-rs/axum/blob/main/examples/query-params-with-empty-strings/src/main.rs
154176
#[cfg_attr(docsrs, doc(cfg(feature = "query")))]
177+
#[deprecated = "Use Option<Path<_>> instead"]
155178
#[derive(Debug, Clone, Copy, Default)]
156179
pub struct OptionalQuery<T>(pub Option<T>);
157180

181+
#[allow(deprecated)]
158182
#[async_trait]
159183
impl<T, S> FromRequestParts<S> for OptionalQuery<T>
160184
where
@@ -175,6 +199,7 @@ where
175199
}
176200
}
177201

202+
#[allow(deprecated)]
178203
impl<T> std::ops::Deref for OptionalQuery<T> {
179204
type Target = Option<T>;
180205

@@ -184,6 +209,7 @@ impl<T> std::ops::Deref for OptionalQuery<T> {
184209
}
185210
}
186211

212+
#[allow(deprecated)]
187213
impl<T> std::ops::DerefMut for OptionalQuery<T> {
188214
#[inline]
189215
fn deref_mut(&mut self) -> &mut Self::Target {
@@ -231,6 +257,7 @@ impl std::error::Error for OptionalQueryRejection {
231257
}
232258

233259
#[cfg(test)]
260+
#[allow(deprecated)]
234261
mod tests {
235262
use super::*;
236263
use crate::test_helpers::*;

0 commit comments

Comments
 (0)