Skip to main content

multipart_write/write/
for_each_recv.rs

1use std::fmt::{self, Debug, Formatter};
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
5use futures_core::{Future, ready};
6
7use crate::{FusedMultipartWrite, MultipartWrite};
8
9pin_project_lite::pin_project! {
10    /// `MultipartWrite` for [`for_each_recv`].
11    ///
12    /// [`for_each_recv`]: super::MultipartWriteExt::for_each_recv
13    #[must_use = "futures do nothing unless polled"]
14    pub struct ForEachRecv<Wr, Fut, F> {
15        #[pin]
16        writer: Wr,
17        #[pin]
18        fut: Option<Fut>,
19        f: F,
20    }
21}
22
23impl<Wr, Fut, F> ForEachRecv<Wr, Fut, F> {
24    pub(super) fn new(writer: Wr, f: F) -> Self {
25        Self { writer, fut: None, f }
26    }
27
28    /// Consumes `ForEachRecv`, returning the underlying writer.
29    pub fn into_inner(self) -> Wr {
30        self.writer
31    }
32
33    /// Acquires a reference to the underlying writer.
34    pub fn get_ref(&self) -> &Wr {
35        &self.writer
36    }
37
38    /// Acquires a mutable reference to the underlying writer.
39    ///
40    /// It is inadvisable to directly write to the underlying writer.
41    pub fn get_mut(&mut self) -> &mut Wr {
42        &mut self.writer
43    }
44
45    /// Acquires a pinned mutable reference to the underlying writer.
46    ///
47    /// It is inadvisable to directly write to the underlying writer.
48    pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut Wr> {
49        self.project().writer
50    }
51}
52
53impl<Wr, Part, Fut, F> FusedMultipartWrite<Part> for ForEachRecv<Wr, Fut, F>
54where
55    Wr: FusedMultipartWrite<Part>,
56    Wr::Recv: Clone,
57    F: FnMut(Wr::Recv) -> Fut,
58    Fut: Future<Output = ()>,
59{
60    fn is_terminated(&self) -> bool {
61        self.writer.is_terminated() && self.fut.is_none()
62    }
63}
64
65impl<Wr, Part, Fut, F> MultipartWrite<Part> for ForEachRecv<Wr, Fut, F>
66where
67    Wr: MultipartWrite<Part>,
68    Wr::Recv: Clone,
69    F: FnMut(Wr::Recv) -> Fut,
70    Fut: Future<Output = ()>,
71{
72    type Error = Wr::Error;
73    type Output = Wr::Output;
74    type Recv = Wr::Recv;
75
76    fn poll_ready(
77        self: Pin<&mut Self>,
78        cx: &mut Context<'_>,
79    ) -> Poll<Result<(), Self::Error>> {
80        let mut this = self.project();
81        if let Some(fut) = this.fut.as_mut().as_pin_mut() {
82            ready!(fut.poll(cx));
83            this.fut.set(None);
84        }
85        this.writer.poll_ready(cx)
86    }
87
88    fn start_send(
89        self: Pin<&mut Self>,
90        part: Part,
91    ) -> Result<Self::Recv, Self::Error> {
92        let mut this = self.project();
93        let recv = this.writer.as_mut().start_send(part)?;
94        let fut = (this.f)(recv.clone());
95        this.fut.set(Some(fut));
96        Ok(recv)
97    }
98
99    fn poll_flush(
100        self: Pin<&mut Self>,
101        cx: &mut Context<'_>,
102    ) -> Poll<Result<(), Self::Error>> {
103        self.project().writer.poll_flush(cx)
104    }
105
106    fn poll_complete(
107        self: Pin<&mut Self>,
108        cx: &mut Context<'_>,
109    ) -> Poll<Result<Self::Output, Self::Error>> {
110        self.project().writer.poll_complete(cx)
111    }
112}
113
114impl<Wr, Fut, F> Debug for ForEachRecv<Wr, Fut, F>
115where
116    Wr: Debug,
117    Fut: Debug,
118{
119    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
120        f.debug_struct("ForEachRecv")
121            .field("writer", &self.writer)
122            .field("fut", &self.fut)
123            .finish()
124    }
125}