use crate::Body; use pin_project_lite::pin_project; use std::{ any::type_name, fmt, pin::Pin, task::{Context, Poll}, }; pin_project! { /// Body returned by the [`map_err`] combinator. /// /// [`map_err`]: crate::util::BodyExt::map_err #[derive(Clone, Copy)] pub struct MapErr { #[pin] inner: B, f: F } } impl MapErr { #[inline] pub(crate) fn new(body: B, f: F) -> Self { Self { inner: body, f } } /// Get a reference to the inner body pub fn get_ref(&self) -> &B { &self.inner } /// Get a mutable reference to the inner body pub fn get_mut(&mut self) -> &mut B { &mut self.inner } /// Get a pinned mutable reference to the inner body pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut B> { self.project().inner } /// Consume `self`, returning the inner body pub fn into_inner(self) -> B { self.inner } } impl Body for MapErr where B: Body, F: FnMut(B::Error) -> E, { type Data = B::Data; type Error = E; fn poll_data( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll>> { let this = self.project(); match this.inner.poll_data(cx) { Poll::Pending => Poll::Pending, Poll::Ready(None) => Poll::Ready(None), Poll::Ready(Some(Ok(data))) => Poll::Ready(Some(Ok(data))), Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err((this.f)(err)))), } } fn poll_trailers( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll, Self::Error>> { let this = self.project(); this.inner.poll_trailers(cx).map_err(this.f) } fn is_end_stream(&self) -> bool { self.inner.is_end_stream() } fn size_hint(&self) -> crate::SizeHint { self.inner.size_hint() } } impl fmt::Debug for MapErr where B: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("MapErr") .field("inner", &self.inner) .field("f", &type_name::()) .finish() } }