multipart_write/write/mod.rs
1//! `MultipartWrite` combinators.
2//!
3//! This module contains the trait [`MultipartWriteExt`], which provides adapters
4//! for chaining and composing `MultipartWrite`rs.
5use crate::{BoxMultipartWrite, LocalBoxMultipartWrite, MultipartWrite};
6
7use futures_core::future::Future;
8use std::pin::Pin;
9use std::task::{Context, Poll};
10
11mod and_then;
12pub use and_then::AndThen;
13
14mod buffered;
15pub use buffered::Buffered;
16
17mod complete;
18pub use complete::Complete;
19
20mod extend;
21pub use extend::{Extend, extend};
22
23mod fanout;
24pub use fanout::Fanout;
25
26mod feed;
27pub use feed::Feed;
28
29mod filter;
30pub use filter::Filter;
31
32mod filter_map;
33pub use filter_map::FilterMap;
34
35mod fold_ret;
36pub use fold_ret::FoldRet;
37
38mod flush;
39pub use flush::Flush;
40
41mod fuse;
42pub use fuse::Fuse;
43
44mod lift;
45pub use lift::Lift;
46
47mod map_err;
48pub use map_err::MapErr;
49
50mod map_ret;
51pub use map_ret::MapRet;
52
53mod map_ok;
54pub use map_ok::MapOk;
55
56mod resolve;
57pub use resolve::{Resolve, resolve};
58
59mod send_part;
60pub use send_part::SendPart;
61
62mod then;
63pub use then::Then;
64
65mod with;
66pub use with::With;
67
68impl<Wr: MultipartWrite<Part>, Part> MultipartWriteExt<Part> for Wr {}
69
70/// An extension trait for `MultipartWrite` providing a variety of convenient
71/// combinator functions.
72pub trait MultipartWriteExt<Part>: MultipartWrite<Part> {
73 /// Compute from this writer's output type a new output of a different type
74 /// using an asynchronous closure.
75 ///
76 /// Calling `poll_complete` on this writer will complete the inner writer,
77 /// then run the provided closure `f` with the output to produce the final
78 /// output of this writer.
79 fn and_then<T, E, Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
80 where
81 F: FnMut(Self::Output) -> Fut,
82 Fut: Future<Output = Result<T, E>>,
83 E: From<Self::Error>,
84 Self: Sized,
85 {
86 AndThen::new(self, f)
87 }
88
89 /// Wrap this writer in a `Box`, pinning it.
90 fn boxed<'a>(self) -> BoxMultipartWrite<'a, Part, Self::Ret, Self::Output, Self::Error>
91 where
92 Self: Sized + Send + 'a,
93 {
94 Box::pin(self)
95 }
96
97 /// Wrap this writer in a `Box`, pinning it.
98 ///
99 /// Similar to `boxed` but without the `Send` requirement.
100 fn boxed_local<'a>(
101 self,
102 ) -> LocalBoxMultipartWrite<'a, Part, Self::Ret, Self::Output, Self::Error>
103 where
104 Self: Sized + 'a,
105 {
106 Box::pin(self)
107 }
108
109 /// Adds a fixed size buffer to the current writer.
110 ///
111 /// The resulting `MultipartWrite` will buffer up to `capacity` items when
112 /// the underlying writer is not able to accept new parts.
113 fn buffered(self, capacity: impl Into<Option<usize>>) -> Buffered<Self, Part>
114 where
115 Self: Sized,
116 {
117 Buffered::new(self, capacity.into().unwrap_or_default())
118 }
119
120 /// A future that runs this writer to completion, returning the associated
121 /// output.
122 fn complete(&mut self) -> Complete<'_, Self, Part>
123 where
124 Self: Unpin,
125 {
126 Complete::new(self)
127 }
128
129 /// Fanout the part to multiple writers.
130 ///
131 /// This adapter clones each incoming part and forwards it to both writers.
132 fn fanout<U>(self, other: U) -> Fanout<Self, U, Part>
133 where
134 Part: Clone,
135 U: MultipartWrite<Part, Error = Self::Error>,
136 Self: Sized,
137 {
138 Fanout::new(self, other)
139 }
140
141 /// A future that completes after the given part has been received by the
142 /// writer.
143 ///
144 /// Unlike `send_part`, the returned future does not flush the writer. It is
145 /// the caller's responsibility to ensure all pending items are processed,
146 /// which can be done with `flush` or `complete`.
147 fn feed(&mut self, part: Part) -> Feed<'_, Self, Part>
148 where
149 Self: Unpin,
150 {
151 Feed::new(self, part)
152 }
153
154 /// Apply a filter to this writer's parts, returning a new writer with the
155 /// same output.
156 ///
157 /// The return type of this writer is `Option<Self::Ret>` and is `None` when
158 /// the part did not pass the filter.
159 fn filter<F>(self, f: F) -> Filter<Self, F>
160 where
161 F: FnMut(&Part) -> bool,
162 Self: Sized,
163 {
164 Filter::new(self, f)
165 }
166
167 /// Attempt to map the input to a part for this writer, filtering out the
168 /// inputs where the mapping returns `None`.
169 ///
170 /// The return type of this writer is `Option<Self::Ret>` and is `None` when
171 /// the mapping of the input `U` did not pass the filter.
172 fn filter_map<U, F>(self, f: F) -> FilterMap<Self, F>
173 where
174 F: FnMut(U) -> Option<Part>,
175 Self: Sized,
176 {
177 FilterMap::new(self, f)
178 }
179
180 /// A future that completes when the underlying writer has been flushed.
181 fn flush(&mut self) -> Flush<'_, Self, Part>
182 where
183 Self: Unpin,
184 {
185 Flush::new(self)
186 }
187
188 /// Accumulate this writer's returned values, returning a new multipart
189 /// writer that pairs the underlying writer's output with the
190 /// result of the accumulating function.
191 fn fold_ret<T, F>(self, id: T, f: F) -> FoldRet<Self, T, F>
192 where
193 F: FnMut(T, &Self::Ret) -> T,
194 Self: Sized,
195 {
196 FoldRet::new(self, id, f)
197 }
198
199 /// Returns a new writer that fuses according to the provided closure.
200 ///
201 /// The resulting writer wraps both `Self::Ret` and `Self::Output` in an
202 /// `Option` and is guaranted to both output and return `Ok(None)` when
203 /// called after becoming fused.
204 fn fuse<F>(self, f: F) -> Fuse<Self, F>
205 where
206 F: FnMut(&Self::Output) -> bool,
207 Self: Sized,
208 {
209 Fuse::new(self, f)
210 }
211
212 /// "Lift" the multipart writer `U` in front of this one.
213 ///
214 /// The result is a new multipart writer that writes parts for `U`, using the
215 /// output of `U` to source the parts to write to this writer, and resolving
216 /// to the output of this writer when polled to completion.
217 ///
218 /// In other words, it expresses this multipart writer as being built from
219 /// the parts of another multipart writer.
220 fn lift<U, T>(self, other: U) -> Lift<Self, U, Part>
221 where
222 U: MultipartWrite<T, Output = Part>,
223 Self: MultipartWrite<Part> + Sized,
224 Self::Error: From<U::Error>,
225 {
226 Lift::new(self, other)
227 }
228
229 /// Map this writer's error type to a different value, returning a new
230 /// multipart writer with the given error type.
231 fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
232 where
233 F: FnMut(Self::Error) -> E,
234 Self: Sized,
235 {
236 MapErr::new(self, f)
237 }
238
239 /// Map this writer's output type to a different type, returning a new
240 /// multipart writer with the given output type.
241 fn map_ok<U, F>(self, f: F) -> MapOk<Self, F>
242 where
243 F: FnMut(Self::Output) -> U,
244 Self: Sized,
245 {
246 MapOk::new(self, f)
247 }
248
249 /// Map this writer's return type to a different value, returning a new
250 /// multipart writer with the given return type.
251 fn map_ret<U, F>(self, f: F) -> MapRet<Self, F>
252 where
253 F: FnMut(Self::Ret) -> U,
254 Self: Sized,
255 {
256 MapRet::new(self, f)
257 }
258
259 /// A convenience method for calling [`MultipartWrite::poll_ready`] on
260 /// [`Unpin`] writer types.
261 #[must_use = "futures do nothing unless polled"]
262 fn poll_ready_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
263 where
264 Self: Unpin,
265 {
266 Pin::new(self).poll_ready(cx)
267 }
268
269 /// A convenience method for calling [`MultipartWrite::poll_flush`] on
270 /// [`Unpin`] writer types.
271 #[must_use = "futures do nothing unless polled"]
272 fn poll_flush_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
273 where
274 Self: Unpin,
275 {
276 Pin::new(self).poll_flush(cx)
277 }
278
279 /// A convenience method for calling [`MultipartWrite::poll_complete`] on
280 /// [`Unpin`] writer types.
281 #[must_use = "futures do nothing unless polled"]
282 fn poll_complete_unpin(
283 &mut self,
284 cx: &mut Context<'_>,
285 ) -> Poll<Result<Self::Output, Self::Error>>
286 where
287 Self: Unpin,
288 {
289 Pin::new(self).poll_complete(cx)
290 }
291
292 /// A future that completes when a part has been fully processed into the
293 /// writer, including flushing.
294 fn send_part(&mut self, part: Part) -> SendPart<'_, Self, Part>
295 where
296 Self: Unpin,
297 {
298 SendPart::new(self, part)
299 }
300
301 /// Chain an asynchronous computation on the result of polling the writer for
302 /// completion.
303 fn then<T, E, Fut, F>(self, f: F) -> Then<Self, Fut, F>
304 where
305 F: FnMut(Result<Self::Output, Self::Error>) -> Fut,
306 Fut: Future<Output = Result<T, E>>,
307 E: From<Self::Error>,
308 Self: Sized,
309 {
310 Then::new(self, f)
311 }
312
313 /// Provide a part to this writer in the output of a future.
314 ///
315 /// The result is a new writer over the type `U` that passes each value
316 /// through the function `f`, resolving the output, and sending it to the
317 /// inner writer.
318 fn with<U, E, Fut, F>(self, f: F) -> With<Self, Part, Fut, F>
319 where
320 F: FnMut(U) -> Fut,
321 Fut: Future<Output = Result<Part, E>>,
322 E: From<Self::Error>,
323 Self: Sized,
324 {
325 With::new(self, f)
326 }
327}