mirror of
https://github.com/fafhrd91/actix-web
synced 2025-08-30 16:40:21 +02:00
add associated error type to MessageBody (#2183)
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
//! [`MessageBody`] trait and foreign implementations.
|
||||
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
mem,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use futures_core::ready;
|
||||
use pin_project_lite::pin_project;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
@@ -14,6 +17,8 @@ use super::BodySize;
|
||||
|
||||
/// An interface for response bodies.
|
||||
pub trait MessageBody {
|
||||
type Error;
|
||||
|
||||
/// Body size hint.
|
||||
fn size(&self) -> BodySize;
|
||||
|
||||
@@ -21,14 +26,12 @@ pub trait MessageBody {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>>;
|
||||
|
||||
downcast_get_type_id!();
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>>;
|
||||
}
|
||||
|
||||
downcast!(MessageBody);
|
||||
|
||||
impl MessageBody for () {
|
||||
type Error = Infallible;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Empty
|
||||
}
|
||||
@@ -36,12 +39,18 @@ impl MessageBody for () {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
Poll::Ready(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MessageBody + Unpin> MessageBody for Box<T> {
|
||||
impl<B> MessageBody for Box<B>
|
||||
where
|
||||
B: MessageBody + Unpin,
|
||||
B::Error: Into<Error>,
|
||||
{
|
||||
type Error = B::Error;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
self.as_ref().size()
|
||||
}
|
||||
@@ -49,12 +58,18 @@ impl<T: MessageBody + Unpin> MessageBody for Box<T> {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
Pin::new(self.get_mut().as_mut()).poll_next(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MessageBody> MessageBody for Pin<Box<T>> {
|
||||
impl<B> MessageBody for Pin<Box<B>>
|
||||
where
|
||||
B: MessageBody,
|
||||
B::Error: Into<Error>,
|
||||
{
|
||||
type Error = B::Error;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
self.as_ref().size()
|
||||
}
|
||||
@@ -62,12 +77,14 @@ impl<T: MessageBody> MessageBody for Pin<Box<T>> {
|
||||
fn poll_next(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
self.as_mut().poll_next(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageBody for Bytes {
|
||||
type Error = Infallible;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.len() as u64)
|
||||
}
|
||||
@@ -75,7 +92,7 @@ impl MessageBody for Bytes {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -85,6 +102,8 @@ impl MessageBody for Bytes {
|
||||
}
|
||||
|
||||
impl MessageBody for BytesMut {
|
||||
type Error = Infallible;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.len() as u64)
|
||||
}
|
||||
@@ -92,7 +111,7 @@ impl MessageBody for BytesMut {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -102,6 +121,8 @@ impl MessageBody for BytesMut {
|
||||
}
|
||||
|
||||
impl MessageBody for &'static str {
|
||||
type Error = Infallible;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.len() as u64)
|
||||
}
|
||||
@@ -109,7 +130,7 @@ impl MessageBody for &'static str {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -121,6 +142,8 @@ impl MessageBody for &'static str {
|
||||
}
|
||||
|
||||
impl MessageBody for Vec<u8> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.len() as u64)
|
||||
}
|
||||
@@ -128,7 +151,7 @@ impl MessageBody for Vec<u8> {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -138,6 +161,8 @@ impl MessageBody for Vec<u8> {
|
||||
}
|
||||
|
||||
impl MessageBody for String {
|
||||
type Error = Infallible;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
BodySize::Sized(self.len() as u64)
|
||||
}
|
||||
@@ -145,7 +170,7 @@ impl MessageBody for String {
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Error>>> {
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
if self.is_empty() {
|
||||
Poll::Ready(None)
|
||||
} else {
|
||||
@@ -155,3 +180,53 @@ impl MessageBody for String {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin_project! {
|
||||
pub(crate) struct MessageBodyMapErr<B, F> {
|
||||
#[pin]
|
||||
body: B,
|
||||
mapper: Option<F>,
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, F, E> MessageBodyMapErr<B, F>
|
||||
where
|
||||
B: MessageBody,
|
||||
F: FnOnce(B::Error) -> E,
|
||||
{
|
||||
pub(crate) fn new(body: B, mapper: F) -> Self {
|
||||
Self {
|
||||
body,
|
||||
mapper: Some(mapper),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, F, E> MessageBody for MessageBodyMapErr<B, F>
|
||||
where
|
||||
B: MessageBody,
|
||||
F: FnOnce(B::Error) -> E,
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn size(&self) -> BodySize {
|
||||
self.body.size()
|
||||
}
|
||||
|
||||
fn poll_next(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||
let this = self.as_mut().project();
|
||||
|
||||
match ready!(this.body.poll_next(cx)) {
|
||||
Some(Err(err)) => {
|
||||
let f = self.as_mut().project().mapper.take().unwrap();
|
||||
let mapped_err = (f)(err);
|
||||
Poll::Ready(Some(Err(mapped_err)))
|
||||
}
|
||||
Some(Ok(val)) => Poll::Ready(Some(Ok(val))),
|
||||
None => Poll::Ready(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user