1 use crate::Body; 2 use pin_project_lite::pin_project; 3 use std::{ 4 any::type_name, 5 fmt, 6 pin::Pin, 7 task::{Context, Poll}, 8 }; 9 10 pin_project! { 11 /// Body returned by the [`map_err`] combinator. 12 /// 13 /// [`map_err`]: crate::util::BodyExt::map_err 14 #[derive(Clone, Copy)] 15 pub struct MapErr<B, F> { 16 #[pin] 17 inner: B, 18 f: F 19 } 20 } 21 22 impl<B, F> MapErr<B, F> { 23 #[inline] new(body: B, f: F) -> Self24 pub(crate) fn new(body: B, f: F) -> Self { 25 Self { inner: body, f } 26 } 27 28 /// Get a reference to the inner body get_ref(&self) -> &B29 pub fn get_ref(&self) -> &B { 30 &self.inner 31 } 32 33 /// Get a mutable reference to the inner body get_mut(&mut self) -> &mut B34 pub fn get_mut(&mut self) -> &mut B { 35 &mut self.inner 36 } 37 38 /// Get a pinned mutable reference to the inner body get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut B>39 pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut B> { 40 self.project().inner 41 } 42 43 /// Consume `self`, returning the inner body into_inner(self) -> B44 pub fn into_inner(self) -> B { 45 self.inner 46 } 47 } 48 49 impl<B, F, E> Body for MapErr<B, F> 50 where 51 B: Body, 52 F: FnMut(B::Error) -> E, 53 { 54 type Data = B::Data; 55 type Error = E; 56 poll_data( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>57 fn poll_data( 58 self: Pin<&mut Self>, 59 cx: &mut Context<'_>, 60 ) -> Poll<Option<Result<Self::Data, Self::Error>>> { 61 let this = self.project(); 62 match this.inner.poll_data(cx) { 63 Poll::Pending => Poll::Pending, 64 Poll::Ready(None) => Poll::Ready(None), 65 Poll::Ready(Some(Ok(data))) => Poll::Ready(Some(Ok(data))), 66 Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err((this.f)(err)))), 67 } 68 } 69 poll_trailers( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Option<http::HeaderMap>, Self::Error>>70 fn poll_trailers( 71 self: Pin<&mut Self>, 72 cx: &mut Context<'_>, 73 ) -> Poll<Result<Option<http::HeaderMap>, Self::Error>> { 74 let this = self.project(); 75 this.inner.poll_trailers(cx).map_err(this.f) 76 } 77 is_end_stream(&self) -> bool78 fn is_end_stream(&self) -> bool { 79 self.inner.is_end_stream() 80 } 81 size_hint(&self) -> crate::SizeHint82 fn size_hint(&self) -> crate::SizeHint { 83 self.inner.size_hint() 84 } 85 } 86 87 impl<B, F> fmt::Debug for MapErr<B, F> 88 where 89 B: fmt::Debug, 90 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 92 f.debug_struct("MapErr") 93 .field("inner", &self.inner) 94 .field("f", &type_name::<F>()) 95 .finish() 96 } 97 } 98