diff --git a/axum/src/extract/query.rs b/axum/src/extract/query.rs index a0c0f77cbc0..619ce163a4c 100644 --- a/axum/src/extract/query.rs +++ b/axum/src/extract/query.rs @@ -1,4 +1,4 @@ -use super::{rejection::*, FromRequestParts}; +use super::{rejection::*, FromRequestParts, OptionalFromRequestParts}; use async_trait::async_trait; use http::{request::Parts, Uri}; use serde::de::DeserializeOwned; @@ -59,6 +59,28 @@ where } } +#[async_trait] +impl OptionalFromRequestParts for Query +where + T: DeserializeOwned, + S: Send + Sync, +{ + type Rejection = QueryRejection; + + async fn from_request_parts( + parts: &mut Parts, + _state: &S, + ) -> Result, Self::Rejection> { + if let Some(query) = parts.uri.query() { + let value = serde_urlencoded::from_str(query) + .map_err(FailedToDeserializeQueryString::from_err)?; + Ok(Some(Self(value))) + } else { + Ok(None) + } + } +} + impl Query where T: DeserializeOwned,