multipart_write/write/
resolve.rs

1use crate::{FusedMultipartWrite, MultipartWrite};
2
3use futures_core::{Future, ready};
4use std::fmt::{self, Debug, Formatter};
5use std::pin::Pin;
6use std::task::{Context, Poll};
7
8/// Create a `MultipartWrite` from a future that resolves to one.
9pub fn resolve<Wr, E, Fut>(fut: Fut) -> Resolve<Fut, Wr>
10where
11    Fut: Future<Output = Result<Wr, E>>,
12{
13    Resolve::new(fut)
14}
15
16pin_project_lite::pin_project! {
17    /// Writer returned by [`resolve`].
18    #[must_use = "futures do nothing unless polled"]
19    pub struct Resolve<Fut, Wr> {
20        #[pin]
21        fut: Option<Fut>,
22        #[pin]
23        writer: Option<Wr>,
24    }
25}
26
27impl<Fut, Wr> Resolve<Fut, Wr> {
28    fn new(fut: Fut) -> Self {
29        Self {
30            fut: Some(fut),
31            writer: None,
32        }
33    }
34
35    fn poll_writer<E>(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), E>>
36    where
37        Fut: Future<Output = Result<Wr, E>>,
38    {
39        if self.writer.is_some() {
40            return Poll::Ready(Ok(()));
41        }
42        let mut this = self.project();
43        let fut = this
44            .fut
45            .as_mut()
46            .as_pin_mut()
47            .expect("polled Resolve after completion");
48        let writer = ready!(fut.poll(cx))?;
49        this.writer.set(Some(writer));
50        this.fut.set(None);
51
52        Poll::Ready(Ok(()))
53    }
54}
55
56impl<Wr, Part, E, Fut> FusedMultipartWrite<Part> for Resolve<Fut, Wr>
57where
58    Fut: Future<Output = Result<Wr, E>>,
59    Wr: MultipartWrite<Part, Error = E>,
60{
61    fn is_terminated(&self) -> bool {
62        self.fut.is_none() && self.writer.is_none()
63    }
64}
65
66impl<Wr, Part, E, Fut> MultipartWrite<Part> for Resolve<Fut, Wr>
67where
68    Fut: Future<Output = Result<Wr, E>>,
69    Wr: MultipartWrite<Part, Error = E>,
70{
71    type Ret = Wr::Ret;
72    type Error = E;
73    type Output = Wr::Output;
74
75    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
76        ready!(self.as_mut().poll_writer(cx))?;
77
78        let mut this = self.project();
79        assert!(this.writer.is_some());
80
81        this.writer.as_mut().as_pin_mut().unwrap().poll_ready(cx)
82    }
83
84    fn start_send(self: Pin<&mut Self>, part: Part) -> Result<Self::Ret, Self::Error> {
85        let mut this = self.project();
86        let writer = this
87            .writer
88            .as_mut()
89            .as_pin_mut()
90            .expect("polled Resolve after completion");
91        writer.start_send(part)
92    }
93
94    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
95        let mut this = self.project();
96        let writer = this
97            .writer
98            .as_mut()
99            .as_pin_mut()
100            .expect("polled Resolve after completion");
101        writer.poll_flush(cx)
102    }
103
104    fn poll_complete(
105        self: Pin<&mut Self>,
106        cx: &mut Context<'_>,
107    ) -> Poll<Result<Self::Output, Self::Error>> {
108        let mut this = self.project();
109        let writer = this
110            .writer
111            .as_mut()
112            .as_pin_mut()
113            .expect("polled Resolve after completion");
114        let out = ready!(writer.poll_complete(cx));
115        this.writer.set(None);
116
117        Poll::Ready(out)
118    }
119}
120
121impl<Fut, Wr> Debug for Resolve<Fut, Wr>
122where
123    Wr: Debug,
124    Fut: Debug,
125{
126    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
127        f.debug_struct("Resolve")
128            .field("fut", &self.fut)
129            .field("writer", &self.writer)
130            .finish()
131    }
132}