Remove take_* methods from RequestParts for Version, Method, and Uri (#151)

* Remove `RequestParts::take_method`

* Remove `RequestParts::take_uri`

* Remove `RequestParts::take_version`
This commit is contained in:
David Pedersen
2021-08-07 20:24:13 +02:00
committed by GitHub
parent 75b5615ccd
commit 4bb17cbc2d
8 changed files with 51 additions and 116 deletions
+12 -1
View File
@@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
required for returning responses with bodies other than `hyper::Body` from required for returning responses with bodies other than `hyper::Body` from
handlers. See the docs for advice on how to implement `IntoResponse` ([#86](https://github.com/tokio-rs/axum/pull/86)) handlers. See the docs for advice on how to implement `IntoResponse` ([#86](https://github.com/tokio-rs/axum/pull/86))
- Change WebSocket API to use an extractor ([#121](https://github.com/tokio-rs/axum/pull/121)) - Change WebSocket API to use an extractor ([#121](https://github.com/tokio-rs/axum/pull/121))
- Make WebSocket Message an enum ([#116](https://github.com/tokio-rs/axum/pull/116)) - Make WebSocket `Message` an enum ([#116](https://github.com/tokio-rs/axum/pull/116))
- Add `RoutingDsl::or` for combining routes. ([#108](https://github.com/tokio-rs/axum/pull/108)) - Add `RoutingDsl::or` for combining routes. ([#108](https://github.com/tokio-rs/axum/pull/108))
- Ensure a `HandleError` service created from `axum::ServiceExt::handle_error` - Ensure a `HandleError` service created from `axum::ServiceExt::handle_error`
_does not_ implement `RoutingDsl` as that could lead to confusing routing _does not_ implement `RoutingDsl` as that could lead to confusing routing
@@ -33,6 +33,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `ExtractorMiddlewareLayer` - `ExtractorMiddlewareLayer`
- Replace `axum::body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](https://github.com/tokio-rs/axum/pull/150)) - Replace `axum::body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](https://github.com/tokio-rs/axum/pull/150))
- `WebSocket` now uses `axum::Error` as its error type ([#150](https://github.com/tokio-rs/axum/pull/150)) - `WebSocket` now uses `axum::Error` as its error type ([#150](https://github.com/tokio-rs/axum/pull/150))
- `RequestParts` changes:
- `method` new returns an `&http::Method`
- `method_mut` new returns an `&mut http::Method`
- `take_method` has been removed
- `uri` new returns an `&http::Uri`
- `uri_mut` new returns an `&mut http::Uri`
- `take_uri` has been removed
- These rejections have been removed as they're no longer used
- `MethodAlreadyExtracted`
- `UriAlreadyExtracted`
- `VersionAlreadyExtracted`
# 0.1.3 (06. August, 2021) # 0.1.3 (06. August, 2021)
+2 -6
View File
@@ -51,12 +51,8 @@ where
#[allow(warnings)] #[allow(warnings)]
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
if req.method().ok_or(MethodAlreadyExtracted)? == Method::GET { if req.method() == Method::GET {
let query = req let query = req.uri().query().unwrap_or_default();
.uri()
.ok_or(UriAlreadyExtracted)?
.query()
.unwrap_or_default();
let value = serde_urlencoded::from_str(query) let value = serde_urlencoded::from_str(query)
.map_err(FailedToDeserializeQueryString::new::<T, _>)?; .map_err(FailedToDeserializeQueryString::new::<T, _>)?;
Ok(Form(value)) Ok(Form(value))
+23 -58
View File
@@ -368,9 +368,9 @@ pub trait FromRequest<B = crate::body::Body>: Sized {
/// Has several convenience methods for getting owned parts of the request. /// Has several convenience methods for getting owned parts of the request.
#[derive(Debug)] #[derive(Debug)]
pub struct RequestParts<B = crate::body::Body> { pub struct RequestParts<B = crate::body::Body> {
method: Option<Method>, method: Method,
uri: Option<Uri>, uri: Uri,
version: Option<Version>, version: Version,
headers: Option<HeaderMap>, headers: Option<HeaderMap>,
extensions: Option<Extensions>, extensions: Option<Extensions>,
body: Option<B>, body: Option<B>,
@@ -391,9 +391,9 @@ impl<B> RequestParts<B> {
) = req.into_parts(); ) = req.into_parts();
RequestParts { RequestParts {
method: Some(method), method,
uri: Some(uri), uri,
version: Some(version), version,
headers: Some(headers), headers: Some(headers),
extensions: Some(extensions), extensions: Some(extensions),
body: Some(body), body: Some(body),
@@ -413,17 +413,9 @@ impl<B> RequestParts<B> {
let mut req = Request::new(body.take().expect("body already extracted")); let mut req = Request::new(body.take().expect("body already extracted"));
if let Some(method) = method.take() { *req.method_mut() = method.clone();
*req.method_mut() = method; *req.uri_mut() = uri.clone();
} *req.version_mut() = *version;
if let Some(uri) = uri.take() {
*req.uri_mut() = uri;
}
if let Some(version) = version.take() {
*req.version_mut() = version;
}
if let Some(headers) = headers.take() { if let Some(headers) = headers.take() {
*req.headers_mut() = headers; *req.headers_mut() = headers;
@@ -436,61 +428,34 @@ impl<B> RequestParts<B> {
req req
} }
/// Gets a reference to the request method. /// Gets a reference the request method.
/// pub fn method(&self) -> &Method {
/// Returns `None` if the method has been taken by another extractor. &self.method
pub fn method(&self) -> Option<&Method> {
self.method.as_ref()
} }
/// Gets a mutable reference to the request method. /// Gets a mutable reference to the request method.
/// pub fn method_mut(&mut self) -> &mut Method {
/// Returns `None` if the method has been taken by another extractor. &mut self.method
pub fn method_mut(&mut self) -> Option<&mut Method> {
self.method.as_mut()
} }
/// Takes the method out of the request, leaving a `None` in its place. /// Gets a reference the request URI.
pub fn take_method(&mut self) -> Option<Method> { pub fn uri(&self) -> &Uri {
self.method.take() &self.uri
}
/// Gets a reference to the request URI.
///
/// Returns `None` if the URI has been taken by another extractor.
pub fn uri(&self) -> Option<&Uri> {
self.uri.as_ref()
} }
/// Gets a mutable reference to the request URI. /// Gets a mutable reference to the request URI.
/// pub fn uri_mut(&mut self) -> &mut Uri {
/// Returns `None` if the URI has been taken by another extractor. &mut self.uri
pub fn uri_mut(&mut self) -> Option<&mut Uri> {
self.uri.as_mut()
} }
/// Takes the URI out of the request, leaving a `None` in its place. /// Get the request HTTP version.
pub fn take_uri(&mut self) -> Option<Uri> { pub fn version(&self) -> Version {
self.uri.take()
}
/// Gets a reference to the request HTTP version.
///
/// Returns `None` if the HTTP version has been taken by another extractor.
pub fn version(&self) -> Option<Version> {
self.version self.version
} }
/// Gets a mutable reference to the request HTTP version. /// Gets a mutable reference to the request HTTP version.
/// pub fn version_mut(&mut self) -> &mut Version {
/// Returns `None` if the HTTP version has been taken by another extractor. &mut self.version
pub fn version_mut(&mut self) -> Option<&mut Version> {
self.version.as_mut()
}
/// Takes the HTTP version out of the request, leaving a `None` in its place.
pub fn take_version(&mut self) -> Option<Version> {
self.version.take()
} }
/// Gets a reference to the request headers. /// Gets a reference to the request headers.
+1 -5
View File
@@ -47,11 +47,7 @@ where
type Rejection = QueryRejection; type Rejection = QueryRejection;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
let query = req let query = req.uri().query().unwrap_or_default();
.uri()
.ok_or(UriAlreadyExtracted)?
.query()
.unwrap_or_default();
let value = serde_urlencoded::from_str(query) let value = serde_urlencoded::from_str(query)
.map_err(FailedToDeserializeQueryString::new::<T, _>)?; .map_err(FailedToDeserializeQueryString::new::<T, _>)?;
Ok(Query(value)) Ok(Query(value))
+1 -4
View File
@@ -30,10 +30,7 @@ where
type Rejection = Infallible; type Rejection = Infallible;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
let query = req let query = req.uri().query().map(|query| query.to_string());
.uri()
.and_then(|uri| uri.query())
.map(|query| query.to_string());
Ok(Self(query)) Ok(Self(query))
} }
} }
-24
View File
@@ -10,27 +10,6 @@ use http_body::Full;
use std::convert::Infallible; use std::convert::Infallible;
use tower::BoxError; use tower::BoxError;
define_rejection! {
#[status = INTERNAL_SERVER_ERROR]
#[body = "Version taken by other extractor"]
/// Rejection used if the HTTP version has been taken by another extractor.
pub struct VersionAlreadyExtracted;
}
define_rejection! {
#[status = INTERNAL_SERVER_ERROR]
#[body = "URI taken by other extractor"]
/// Rejection used if the URI has been taken by another extractor.
pub struct UriAlreadyExtracted;
}
define_rejection! {
#[status = INTERNAL_SERVER_ERROR]
#[body = "Method taken by other extractor"]
/// Rejection used if the method has been taken by another extractor.
pub struct MethodAlreadyExtracted;
}
define_rejection! { define_rejection! {
#[status = INTERNAL_SERVER_ERROR] #[status = INTERNAL_SERVER_ERROR]
#[body = "Extensions taken by other extractor"] #[body = "Extensions taken by other extractor"]
@@ -222,7 +201,6 @@ composite_rejection! {
/// Contains one variant for each way the [`Query`](super::Query) extractor /// Contains one variant for each way the [`Query`](super::Query) extractor
/// can fail. /// can fail.
pub enum QueryRejection { pub enum QueryRejection {
UriAlreadyExtracted,
FailedToDeserializeQueryString, FailedToDeserializeQueryString,
} }
} }
@@ -237,9 +215,7 @@ composite_rejection! {
FailedToDeserializeQueryString, FailedToDeserializeQueryString,
FailedToBufferBody, FailedToBufferBody,
BodyAlreadyExtracted, BodyAlreadyExtracted,
UriAlreadyExtracted,
HeadersAlreadyExtracted, HeadersAlreadyExtracted,
MethodAlreadyExtracted,
} }
} }
+11 -16
View File
@@ -4,6 +4,7 @@ use bytes::Bytes;
use futures_util::stream::Stream; use futures_util::stream::Stream;
use http::{HeaderMap, Method, Request, Uri, Version}; use http::{HeaderMap, Method, Request, Uri, Version};
use std::{ use std::{
convert::Infallible,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
@@ -18,21 +19,15 @@ where
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
let RequestParts { let RequestParts {
method, method: _,
uri, uri: _,
version, version: _,
headers, headers,
extensions, extensions,
body, body,
} = req; } = req;
let all_parts = method let all_parts = extensions.as_ref().zip(body.as_ref()).zip(headers.as_ref());
.as_ref()
.zip(version.as_ref())
.zip(uri.as_ref())
.zip(extensions.as_ref())
.zip(body.as_ref())
.zip(headers.as_ref());
if all_parts.is_some() { if all_parts.is_some() {
Ok(req.into_request()) Ok(req.into_request())
@@ -60,10 +55,10 @@ impl<B> FromRequest<B> for Method
where where
B: Send, B: Send,
{ {
type Rejection = MethodAlreadyExtracted; type Rejection = Infallible;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
req.take_method().ok_or(MethodAlreadyExtracted) Ok(req.method().clone())
} }
} }
@@ -72,10 +67,10 @@ impl<B> FromRequest<B> for Uri
where where
B: Send, B: Send,
{ {
type Rejection = UriAlreadyExtracted; type Rejection = Infallible;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
req.take_uri().ok_or(UriAlreadyExtracted) Ok(req.uri().clone())
} }
} }
@@ -84,10 +79,10 @@ impl<B> FromRequest<B> for Version
where where
B: Send, B: Send,
{ {
type Rejection = VersionAlreadyExtracted; type Rejection = Infallible;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
req.take_version().ok_or(VersionAlreadyExtracted) Ok(req.version())
} }
} }
+1 -2
View File
@@ -167,7 +167,7 @@ where
type Rejection = WebSocketUpgradeRejection; type Rejection = WebSocketUpgradeRejection;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
if req.method().ok_or(MethodAlreadyExtracted)? != Method::GET { if req.method() != Method::GET {
return Err(MethodNotGet.into()); return Err(MethodNotGet.into());
} }
@@ -572,7 +572,6 @@ pub mod rejection {
InvalidUpgradeHeader, InvalidUpgradeHeader,
InvalidWebsocketVersionHeader, InvalidWebsocketVersionHeader,
WebsocketKeyHeaderMissing, WebsocketKeyHeaderMissing,
MethodAlreadyExtracted,
HeadersAlreadyExtracted, HeadersAlreadyExtracted,
ExtensionsAlreadyExtracted, ExtensionsAlreadyExtracted,
} }