multipart_write/write/
resolve.rs1use std::fmt::{self, Debug, Formatter};
2use std::ops::{Deref, DerefMut};
3use std::pin::Pin;
4use std::task::{Context, Poll};
5
6use futures_core::{Future, ready};
7
8use crate::{FusedMultipartWrite, MultipartWrite};
9
10pub fn resolve<Wr, E, Fut>(fut: Fut) -> Resolve<Fut, Wr>
25where
26 Fut: Future<Output = Result<Wr, E>>,
27{
28 Resolve::new(fut)
29}
30
31pin_project_lite::pin_project! {
32 #[must_use = "futures do nothing unless polled"]
34 pub struct Resolve<Fut, Wr> {
35 #[pin]
36 fut: Option<Fut>,
37 #[pin]
38 writer: Option<Wr>,
39 }
40}
41
42impl<Fut, Wr> Resolve<Fut, Wr> {
43 fn new(fut: Fut) -> Self {
44 Self { fut: Some(fut), writer: None }
45 }
46
47 pub fn has_writer(&self) -> bool {
49 self.writer.is_some()
50 }
51
52 pub fn into_inner(self) -> Option<Wr> {
54 self.writer
55 }
56
57 pub fn as_ref(&self) -> Option<&Wr> {
59 self.writer.as_ref()
60 }
61
62 pub fn as_deref(&self) -> Option<&Wr::Target>
64 where
65 Wr: Deref,
66 {
67 self.writer.as_deref()
68 }
69
70 pub fn as_deref_mut(&mut self) -> Option<&mut Wr::Target>
72 where
73 Wr: DerefMut,
74 {
75 self.writer.as_deref_mut()
76 }
77
78 pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut Wr>> {
80 self.project().writer.as_pin_mut()
81 }
82
83 fn poll_writer<E>(
84 self: Pin<&mut Self>,
85 cx: &mut Context<'_>,
86 ) -> Poll<Result<(), E>>
87 where
88 Fut: Future<Output = Result<Wr, E>>,
89 {
90 if self.writer.is_some() {
91 return Poll::Ready(Ok(()));
92 }
93 let mut this = self.project();
94 let fut = this
95 .fut
96 .as_mut()
97 .as_pin_mut()
98 .expect("missing both writer and future to create it");
99 let writer = ready!(fut.poll(cx))?;
100 this.writer.set(Some(writer));
101 this.fut.set(None);
102
103 Poll::Ready(Ok(()))
104 }
105}
106
107impl<Wr, Part, E, Fut> FusedMultipartWrite<Part> for Resolve<Fut, Wr>
108where
109 Fut: Future<Output = Result<Wr, E>>,
110 Wr: FusedMultipartWrite<Part, Error = E>,
111{
112 fn is_terminated(&self) -> bool {
113 self.fut.is_none()
114 && self.writer.as_ref().is_some_and(|w| w.is_terminated())
115 }
116}
117
118impl<Wr, Part, E, Fut> MultipartWrite<Part> for Resolve<Fut, Wr>
119where
120 Fut: Future<Output = Result<Wr, E>>,
121 Wr: MultipartWrite<Part, Error = E>,
122{
123 type Error = E;
124 type Output = Wr::Output;
125 type Recv = Wr::Recv;
126
127 fn poll_ready(
128 mut self: Pin<&mut Self>,
129 cx: &mut Context<'_>,
130 ) -> Poll<Result<(), Self::Error>> {
131 ready!(self.as_mut().poll_writer(cx))?;
132 let mut this = self.project();
133
134 this.writer
135 .as_mut()
136 .as_pin_mut()
137 .expect("inner writer lost unexpectedly")
138 .poll_ready(cx)
139 }
140
141 fn start_send(
142 self: Pin<&mut Self>,
143 part: Part,
144 ) -> Result<Self::Recv, Self::Error> {
145 let mut this = self.project();
146 let writer = this
147 .writer
148 .as_mut()
149 .as_pin_mut()
150 .expect("start_send with no existing writer");
151 writer.start_send(part)
152 }
153
154 fn poll_flush(
155 self: Pin<&mut Self>,
156 cx: &mut Context<'_>,
157 ) -> Poll<Result<(), Self::Error>> {
158 let mut this = self.project();
159 let writer = this
160 .writer
161 .as_mut()
162 .as_pin_mut()
163 .expect("poll_flush with no existing writer");
164 writer.poll_flush(cx)
165 }
166
167 fn poll_complete(
168 self: Pin<&mut Self>,
169 cx: &mut Context<'_>,
170 ) -> Poll<Result<Self::Output, Self::Error>> {
171 let mut this = self.project();
172 let writer = this
173 .writer
174 .as_mut()
175 .as_pin_mut()
176 .expect("poll_complete with no existing writer");
177 let out = ready!(writer.poll_complete(cx));
178
179 Poll::Ready(out)
180 }
181}
182
183impl<Fut, Wr> Debug for Resolve<Fut, Wr>
184where
185 Wr: Debug,
186 Fut: Debug,
187{
188 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
189 f.debug_struct("Resolve")
190 .field("fut", &self.fut)
191 .field("writer", &self.writer)
192 .finish()
193 }
194}