Skip to content

Commit 6460d88

Browse files
committed
Implement OptionalFromRequestParts for axum-extra's Query<T>
… and deprecate OptionalQuery.
1 parent 42bcd63 commit 6460d88

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

axum-extra/src/extract/mod.rs

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

4343
#[cfg(feature = "query")]
44-
pub use self::query::{OptionalQuery, OptionalQueryRejection, Query, QueryRejection};
44+
#[allow(deprecated)]
45+
pub use self::query::OptionalQuery;
46+
#[cfg(feature = "query")]
47+
pub use self::query::{OptionalQueryRejection, Query, QueryRejection};
4548

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

axum-extra/src/extract/query.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use axum::{
2-
extract::FromRequestParts,
2+
extract::{FromRequestParts, OptionalFromRequestParts},
33
response::{IntoResponse, Response},
44
Error,
55
};
@@ -96,6 +96,27 @@ where
9696
}
9797
}
9898

99+
impl<T, S> OptionalFromRequestParts<S> for Query<T>
100+
where
101+
T: DeserializeOwned,
102+
S: Send + Sync,
103+
{
104+
type Rejection = QueryRejection;
105+
106+
async fn from_request_parts(
107+
parts: &mut Parts,
108+
_state: &S,
109+
) -> Result<Option<Self>, Self::Rejection> {
110+
if let Some(query) = parts.uri.query() {
111+
let value = serde_html_form::from_str(query)
112+
.map_err(|err| QueryRejection::FailedToDeserializeQueryString(Error::new(err)))?;
113+
Ok(Some(Self(value)))
114+
} else {
115+
Ok(None)
116+
}
117+
}
118+
}
119+
99120
axum_core::__impl_deref!(Query);
100121

101122
/// Rejection used for [`Query`].
@@ -182,9 +203,11 @@ impl std::error::Error for QueryRejection {
182203
///
183204
/// [example]: https://github.com/tokio-rs/axum/blob/main/examples/query-params-with-empty-strings/src/main.rs
184205
#[cfg_attr(docsrs, doc(cfg(feature = "query")))]
206+
#[deprecated = "Use Option<Query<_>> instead"]
185207
#[derive(Debug, Clone, Copy, Default)]
186208
pub struct OptionalQuery<T>(pub Option<T>);
187209

210+
#[allow(deprecated)]
188211
impl<T, S> FromRequestParts<S> for OptionalQuery<T>
189212
where
190213
T: DeserializeOwned,
@@ -204,6 +227,7 @@ where
204227
}
205228
}
206229

230+
#[allow(deprecated)]
207231
impl<T> std::ops::Deref for OptionalQuery<T> {
208232
type Target = Option<T>;
209233

@@ -213,6 +237,7 @@ impl<T> std::ops::Deref for OptionalQuery<T> {
213237
}
214238
}
215239

240+
#[allow(deprecated)]
216241
impl<T> std::ops::DerefMut for OptionalQuery<T> {
217242
#[inline]
218243
fn deref_mut(&mut self) -> &mut Self::Target {
@@ -260,6 +285,7 @@ impl std::error::Error for OptionalQueryRejection {
260285
}
261286

262287
#[cfg(test)]
288+
#[allow(deprecated)]
263289
mod tests {
264290
use super::*;
265291
use crate::test_helpers::*;

0 commit comments

Comments
 (0)