Skip to content

Commit 3bb12ab

Browse files
authored
Remove OptionalFromRequestParts impl for Query (#3088)
1 parent 1bc6948 commit 3bb12ab

File tree

6 files changed

+12
-94
lines changed

6 files changed

+12
-94
lines changed

axum-extra/CHANGELOG.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@ and this project adheres to [Semantic Versioning].
77

88
# Unreleased
99

10-
- **breaking:** `axum::extract::ws::Message` now uses `Bytes` in place of `Vec<u8>`,
11-
and a new `Utf8Bytes` type in place of `String`, for its variants ([#3078])
12-
- **changed:** Upgraded `tokio-tungstenite` to 0.26 ([#3078])
10+
- **breaking:** Remove `OptionalFromRequestParts` impl for `Query` ([#3088])
1311
- **changed:** Query/Form: Use `serde_path_to_error` to report fields that failed to parse ([#3081])
1412

15-
[#3078]: https://github.com/tokio-rs/axum/pull/3078
1613
[#3081]: https://github.com/tokio-rs/axum/pull/3081
14+
[#3088]: https://github.com/tokio-rs/axum/pull/3088
1715

1816
# 0.10.0
1917

axum-extra/src/extract/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ pub use self::cookie::SignedCookieJar;
4141
pub use self::form::{Form, FormRejection};
4242

4343
#[cfg(feature = "query")]
44-
#[allow(deprecated)]
4544
pub use self::query::OptionalQuery;
4645
#[cfg(feature = "query")]
4746
pub use self::query::{OptionalQueryRejection, Query, QueryRejection};

axum-extra/src/extract/query.rs

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use axum::{
2-
extract::{FromRequestParts, OptionalFromRequestParts},
2+
extract::FromRequestParts,
33
response::{IntoResponse, Response},
44
Error,
55
};
@@ -18,19 +18,6 @@ use std::fmt;
1818
/// with the `multiple` attribute. Those values can be collected into a `Vec` or other sequential
1919
/// container.
2020
///
21-
/// # `Option<Query<T>>` behavior
22-
///
23-
/// If `Query<T>` itself is used as an extractor and there is no query string in
24-
/// the request URL, `T`'s `Deserialize` implementation is called on an empty
25-
/// string instead.
26-
///
27-
/// You can avoid this by using `Option<Query<T>>`, which gives you `None` in
28-
/// the case that there is no query string in the request URL.
29-
///
30-
/// Note that an empty query string is not the same as no query string, that is
31-
/// `https://example.org/` and `https://example.org/?` are not treated the same
32-
/// in this case.
33-
///
3421
/// # Example
3522
///
3623
/// ```rust,no_run
@@ -111,29 +98,6 @@ where
11198
}
11299
}
113100

114-
impl<T, S> OptionalFromRequestParts<S> for Query<T>
115-
where
116-
T: DeserializeOwned,
117-
S: Send + Sync,
118-
{
119-
type Rejection = QueryRejection;
120-
121-
async fn from_request_parts(
122-
parts: &mut Parts,
123-
_state: &S,
124-
) -> Result<Option<Self>, Self::Rejection> {
125-
if let Some(query) = parts.uri.query() {
126-
let deserializer =
127-
serde_html_form::Deserializer::new(form_urlencoded::parse(query.as_bytes()));
128-
let value = serde_path_to_error::deserialize(deserializer)
129-
.map_err(|err| QueryRejection::FailedToDeserializeQueryString(Error::new(err)))?;
130-
Ok(Some(Self(value)))
131-
} else {
132-
Ok(None)
133-
}
134-
}
135-
}
136-
137101
axum_core::__impl_deref!(Query);
138102

139103
/// Rejection used for [`Query`].
@@ -181,8 +145,8 @@ impl std::error::Error for QueryRejection {
181145
}
182146

183147
/// Extractor that deserializes query strings into `None` if no query parameters are present.
184-
/// Otherwise behaviour is identical to [`Query`]
185148
///
149+
/// Otherwise behaviour is identical to [`Query`].
186150
/// `T` is expected to implement [`serde::Deserialize`].
187151
///
188152
/// # Example
@@ -220,11 +184,9 @@ impl std::error::Error for QueryRejection {
220184
///
221185
/// [example]: https://github.com/tokio-rs/axum/blob/main/examples/query-params-with-empty-strings/src/main.rs
222186
#[cfg_attr(docsrs, doc(cfg(feature = "query")))]
223-
#[deprecated = "Use Option<Query<_>> instead"]
224187
#[derive(Debug, Clone, Copy, Default)]
225188
pub struct OptionalQuery<T>(pub Option<T>);
226189

227-
#[allow(deprecated)]
228190
impl<T, S> FromRequestParts<S> for OptionalQuery<T>
229191
where
230192
T: DeserializeOwned,
@@ -246,7 +208,6 @@ where
246208
}
247209
}
248210

249-
#[allow(deprecated)]
250211
impl<T> std::ops::Deref for OptionalQuery<T> {
251212
type Target = Option<T>;
252213

@@ -256,7 +217,6 @@ impl<T> std::ops::Deref for OptionalQuery<T> {
256217
}
257218
}
258219

259-
#[allow(deprecated)]
260220
impl<T> std::ops::DerefMut for OptionalQuery<T> {
261221
#[inline]
262222
fn deref_mut(&mut self) -> &mut Self::Target {
@@ -304,7 +264,6 @@ impl std::error::Error for OptionalQueryRejection {
304264
}
305265

306266
#[cfg(test)]
307-
#[allow(deprecated)]
308267
mod tests {
309268
use super::*;
310269
use crate::test_helpers::*;

axum/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
# Unreleased
99

10+
- **breaking:** `axum::extract::ws::Message` now uses `Bytes` in place of `Vec<u8>`,
11+
and a new `Utf8Bytes` type in place of `String`, for its variants ([#3078])
12+
- **breaking:** Remove `OptionalFromRequestParts` impl for `Query` ([#3088])
13+
- **changed:** Upgraded `tokio-tungstenite` to 0.26 ([#3078])
1014
- **changed:** Query/Form: Use `serde_path_to_error` to report fields that failed to parse ([#3081])
1115

16+
[#3078]: https://github.com/tokio-rs/axum/pull/3078
1217
[#3081]: https://github.com/tokio-rs/axum/pull/3081
18+
[#3088]: https://github.com/tokio-rs/axum/pull/3088
1319

1420
# 0.8.0
1521

axum/src/docs/extract.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,10 @@ struct Pagination {
108108
per_page: usize,
109109
}
110110
111-
impl Default for Pagination {
112-
fn default() -> Self {
113-
Self { page: 1, per_page: 30 }
114-
}
115-
}
116-
117111
async fn get_user_things(
118112
Path(user_id): Path<Uuid>,
119-
pagination: Option<Query<Pagination>>,
113+
Query(pagination): Query<Pagination>,
120114
) {
121-
let Query(pagination) = pagination.unwrap_or_default();
122-
123115
// ...
124116
}
125117
# let _: Router = app;

axum/src/extract/query.rs

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,11 @@
1-
use super::{rejection::*, FromRequestParts, OptionalFromRequestParts};
1+
use super::{rejection::*, FromRequestParts};
22
use http::{request::Parts, Uri};
33
use serde::de::DeserializeOwned;
44

55
/// Extractor that deserializes query strings into some type.
66
///
77
/// `T` is expected to implement [`serde::Deserialize`].
88
///
9-
/// # `Option<Query<T>>` behavior
10-
///
11-
/// If `Query<T>` itself is used as an extractor and there is no query string in
12-
/// the request URL, `T`'s `Deserialize` implementation is called on an empty
13-
/// string instead.
14-
///
15-
/// You can avoid this by using `Option<Query<T>>`, which gives you `None` in
16-
/// the case that there is no query string in the request URL.
17-
///
18-
/// Note that an empty query string is not the same as no query string, that is
19-
/// `https://example.org/` and `https://example.org/?` are not treated the same
20-
/// in this case.
21-
///
229
/// # Examples
2310
///
2411
/// ```rust,no_run
@@ -75,29 +62,6 @@ where
7562
}
7663
}
7764

78-
impl<T, S> OptionalFromRequestParts<S> for Query<T>
79-
where
80-
T: DeserializeOwned,
81-
S: Send + Sync,
82-
{
83-
type Rejection = QueryRejection;
84-
85-
async fn from_request_parts(
86-
parts: &mut Parts,
87-
_state: &S,
88-
) -> Result<Option<Self>, Self::Rejection> {
89-
if let Some(query) = parts.uri.query() {
90-
let deserializer =
91-
serde_urlencoded::Deserializer::new(form_urlencoded::parse(query.as_bytes()));
92-
let value = serde_path_to_error::deserialize(deserializer)
93-
.map_err(FailedToDeserializeQueryString::from_err)?;
94-
Ok(Some(Self(value)))
95-
} else {
96-
Ok(None)
97-
}
98-
}
99-
}
100-
10165
impl<T> Query<T>
10266
where
10367
T: DeserializeOwned,

0 commit comments

Comments
 (0)