http_body_util/combinators/
inspect_frame.rs1use 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 #[derive(Clone, Copy)]
15 pub struct InspectFrame<B, F> {
16 #[pin]
17 inner: B,
18 f: F
19 }
20}
21
22impl<B, F> InspectFrame<B, F> {
23 #[inline]
24 pub(crate) fn new(body: B, f: F) -> Self {
25 Self { inner: body, f }
26 }
27
28 pub fn get_ref(&self) -> &B {
30 &self.inner
31 }
32
33 pub fn get_mut(&mut self) -> &mut B {
35 &mut self.inner
36 }
37
38 pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut B> {
40 self.project().inner
41 }
42
43 pub fn into_inner(self) -> B {
45 self.inner
46 }
47}
48
49impl<B, F> Body for InspectFrame<B, F>
50where
51 B: Body,
52 F: FnMut(&Frame<B::Data>),
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(Err(err))) => Poll::Ready(Some(Err(err))),
66 Poll::Ready(Some(Ok(frame))) => {
67 (this.f)(&frame);
68 Poll::Ready(Some(Ok(frame)))
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 InspectFrame<B, F>
83where
84 B: fmt::Debug,
85{
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 f.debug_struct("InspectFrame")
88 .field("inner", &self.inner)
89 .field("f", &type_name::<F>())
90 .finish()
91 }
92}