multipart_write/write/
resolve.rs1use 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
8pub 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 #[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}