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