1use crate::Body;
2use pin_project_lite::pin_project;
3use std::{
4 any::type_name,
5 fmt,
6 pin::Pin,
7 task::{Context, Poll},
8};
9
10pin_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
22impl<B, F> MapErr<B, F> {
23 #[inline]
24 pub(crate) fn new(body: B, f: F) -> Self {
25 Self { inner: body, f }
26 }
27
28 /// Get a reference to the inner body
29 pub fn get_ref(&self) -> &B {
30 &self.inner
31 }
32
33 /// Get a mutable reference to the inner body
34 pub fn get_mut(&mut self) -> &mut B {
35 &mut self.inner
36 }
37
38 /// Get a pinned mutable reference to the inner body
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
44 pub fn into_inner(self) -> B {
45 self.inner
46 }
47}
48
49impl<B, F, E> Body for MapErr<B, F>
50where
51 B: Body,
52 F: FnMut(B::Error) -> E,
53{
54 type Data = B::Data;
55 type Error = E;
56
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
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
78 fn is_end_stream(&self) -> bool {
79 self.inner.is_end_stream()
80 }
81
82 fn size_hint(&self) -> crate::SizeHint {
83 self.inner.size_hint()
84 }
85}
86
87impl<B, F> fmt::Debug for MapErr<B, F>
88where
89 B: fmt::Debug,
90{
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 f&mut DebugStruct<'_, '_>.debug_struct("MapErr")
93 .field("inner", &self.inner)
94 .field(name:"f", &type_name::<F>())
95 .finish()
96 }
97}
98