Skip to main content

http_body_util/combinators/
inspect_err.rs

1use http_body::{Body, Frame};
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 [`inspect_err()`] combinator.
12    ///
13    /// [`inspect_err()`]: crate::BodyExt::inspect_err
14    #[derive(Clone, Copy)]
15    pub struct InspectErr<B, F> {
16        #[pin]
17        inner: B,
18        f: F
19    }
20}
21
22impl<B, F> InspectErr<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> Body for InspectErr<B, F>
50where
51    B: Body,
52    F: FnMut(&B::Error),
53{
54    type Data = B::Data;
55    type Error = B::Error;
56
57    fn poll_frame(
58        self: Pin<&mut Self>,
59        cx: &mut Context<'_>,
60    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
61        let this = self.project();
62        match this.inner.poll_frame(cx) {
63            Poll::Pending => Poll::Pending,
64            Poll::Ready(None) => Poll::Ready(None),
65            Poll::Ready(Some(Ok(frame))) => Poll::Ready(Some(Ok(frame))),
66            Poll::Ready(Some(Err(err))) => {
67                (this.f)(&err);
68                Poll::Ready(Some(Err(err)))
69            }
70        }
71    }
72
73    fn size_hint(&self) -> http_body::SizeHint {
74        self.inner.size_hint()
75    }
76
77    fn is_end_stream(&self) -> bool {
78        self.inner.is_end_stream()
79    }
80}
81
82impl<B, F> fmt::Debug for InspectErr<B, F>
83where
84    B: fmt::Debug,
85{
86    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87        f.debug_struct("InspectErr")
88            .field("inner", &self.inner)
89            .field("f", &type_name::<F>())
90            .finish()
91    }
92}