Make extractors easier to write (#36)

Previously extractors worked directly on `Request<B>` which meant you
had to do weird tricks like `mem::take(req.headers_mut())` to get owned
parts of the request.

This changes that instead to use a new `RequestParts` type that have
methods to "take" each part of the request. Without having to do weird
tricks.

Also removed the need to have `B: Default` for body extractors.
This commit is contained in:
David Pedersen
2021-07-22 13:23:50 +02:00
committed by GitHub
parent e544fe1c39
commit f32d325e55
12 changed files with 441 additions and 193 deletions
+5 -3
View File
@@ -2,7 +2,7 @@
//!
//! See [`Multipart`] for more details.
use super::{rejection::*, BodyStream, FromRequest};
use super::{rejection::*, BodyStream, FromRequest, RequestParts};
use async_trait::async_trait;
use bytes::Bytes;
use futures_util::stream::Stream;
@@ -53,9 +53,10 @@ where
{
type Rejection = MultipartRejection;
async fn from_request(req: &mut http::Request<B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
let stream = BodyStream::from_request(req).await?;
let boundary = parse_boundary(req.headers()).ok_or(InvalidBoundary)?;
let headers = req.headers().ok_or(HeadersAlreadyExtracted)?;
let boundary = parse_boundary(headers).ok_or(InvalidBoundary)?;
let multipart = multer::Multipart::new(stream, boundary);
Ok(Self { inner: multipart })
}
@@ -175,6 +176,7 @@ composite_rejection! {
pub enum MultipartRejection {
BodyAlreadyExtracted,
InvalidBoundary,
HeadersAlreadyExtracted,
}
}