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        assert_writer::<Part, Self::Ret, E, T, _>(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        assert_writer::<Part, (), Self::Error, Self::Output, _>(Buffered::new(
118            self,
119            capacity.into().unwrap_or_default(),
120        ))
121    }
122
123    /// A future that runs this writer to completion, returning the associated
124    /// output.
125    fn complete(&mut self) -> Complete<'_, Self, Part>
126    where
127        Self: Unpin,
128    {
129        Complete::new(self)
130    }
131
132    /// Fanout the part to multiple writers.
133    ///
134    /// This adapter clones each incoming part and forwards it to both writers.
135    fn fanout<U>(self, other: U) -> Fanout<Self, U, Part>
136    where
137        Part: Clone,
138        U: MultipartWrite<Part, Error = Self::Error>,
139        Self: Sized,
140    {
141        assert_writer::<Part, (Self::Ret, U::Ret), Self::Error, (Self::Output, U::Output), _>(
142            Fanout::new(self, other),
143        )
144    }
145
146    /// A future that completes after the given part has been received by the
147    /// writer.
148    ///
149    /// Unlike `send_part`, the returned future does not flush the writer.  It is
150    /// the caller's responsibility to ensure all pending items are processed,
151    /// which can be done with `flush` or `complete`.
152    fn feed(&mut self, part: Part) -> Feed<'_, Self, Part>
153    where
154        Self: Unpin,
155    {
156        Feed::new(self, part)
157    }
158
159    /// Apply a filter to this writer's parts, returning a new writer with the
160    /// same output.
161    ///
162    /// The return type of this writer is `Option<Self::Ret>` and is `None` when
163    /// the part did not pass the filter.
164    fn filter<F>(self, f: F) -> Filter<Self, F>
165    where
166        F: FnMut(&Part) -> bool,
167        Self: Sized,
168    {
169        assert_writer::<Part, Option<Self::Ret>, Self::Error, Self::Output, _>(Filter::new(self, f))
170    }
171
172    /// Attempt to map the input to a part for this writer, filtering out the
173    /// inputs where the mapping returns `None`.
174    ///
175    /// The return type of this writer is `Option<Self::Ret>` and is `None` when
176    /// the mapping of the input `U` did not pass the filter.
177    fn filter_map<U, F>(self, f: F) -> FilterMap<Self, F>
178    where
179        F: FnMut(U) -> Option<Part>,
180        Self: Sized,
181    {
182        assert_writer::<U, Option<Self::Ret>, Self::Error, Self::Output, _>(FilterMap::new(self, f))
183    }
184
185    /// A future that completes when the underlying writer has been flushed.
186    fn flush(&mut self) -> Flush<'_, Self, Part>
187    where
188        Self: Unpin,
189    {
190        Flush::new(self)
191    }
192
193    /// Accumulate this writer's returned values, returning a new multipart
194    /// writer that pairs the underlying writer's output with the
195    /// result of the accumulating function.
196    fn fold_ret<T, F>(self, id: T, f: F) -> FoldRet<Self, T, F>
197    where
198        F: FnMut(T, &Self::Ret) -> T,
199        Self: Sized,
200    {
201        assert_writer::<Part, Self::Ret, Self::Error, (T, Self::Output), _>(FoldRet::new(
202            self, id, f,
203        ))
204    }
205
206    /// Returns a new writer that fuses according to the provided closure.
207    ///
208    /// The resulting writer wraps both `Self::Ret` and `Self::Output` in an
209    /// `Option` and is guaranted to both output and return `Ok(None)` when
210    /// called after becoming fused.
211    fn fuse<F>(self, f: F) -> Fuse<Self, F>
212    where
213        F: FnMut(&Self::Output) -> bool,
214        Self: Sized,
215    {
216        assert_writer::<Part, Option<Self::Ret>, Self::Error, Option<Self::Output>, _>(Fuse::new(
217            self, f,
218        ))
219    }
220
221    /// "Lift" the multipart writer `U` in front of this one.
222    ///
223    /// The result is a new multipart writer that writes parts for `U`, using the
224    /// output of `U` to source the parts to write to this writer, and resolving
225    /// to the output of this writer when polled to completion.
226    ///
227    /// In other words, it expresses this multipart writer as being built from
228    /// the parts of another multipart writer.
229    fn lift<U, T>(self, other: U) -> Lift<Self, U, Part>
230    where
231        Self: Sized,
232        Self::Error: From<U::Error>,
233        U: MultipartWrite<T, Output = Part>,
234    {
235        assert_writer::<T, U::Ret, Self::Error, Self::Output, _>(Lift::new(self, other))
236    }
237
238    /// Map this writer's error type to a different value, returning a new
239    /// multipart writer with the given error type.
240    fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
241    where
242        F: FnMut(Self::Error) -> E,
243        Self: Sized,
244    {
245        assert_writer::<Part, Self::Ret, E, Self::Output, _>(MapErr::new(self, f))
246    }
247
248    /// Map this writer's output type to a different type, returning a new
249    /// multipart writer with the given output type.
250    fn map_ok<U, F>(self, f: F) -> MapOk<Self, F>
251    where
252        F: FnMut(Self::Output) -> U,
253        Self: Sized,
254    {
255        assert_writer::<Part, Self::Ret, Self::Error, U, _>(MapOk::new(self, f))
256    }
257
258    /// Map this writer's return type to a different value, returning a new
259    /// multipart writer with the given return type.
260    fn map_ret<U, F>(self, f: F) -> MapRet<Self, F>
261    where
262        F: FnMut(Self::Ret) -> U,
263        Self: Sized,
264    {
265        assert_writer::<Part, U, Self::Error, Self::Output, _>(MapRet::new(self, f))
266    }
267
268    /// A convenience method for calling [`MultipartWrite::poll_ready`] on
269    /// [`Unpin`] writer types.
270    #[must_use = "futures do nothing unless polled"]
271    fn poll_ready_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
272    where
273        Self: Unpin,
274    {
275        Pin::new(self).poll_ready(cx)
276    }
277
278    /// A convenience method for calling [`MultipartWrite::poll_flush`] on
279    /// [`Unpin`] writer types.
280    #[must_use = "futures do nothing unless polled"]
281    fn poll_flush_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
282    where
283        Self: Unpin,
284    {
285        Pin::new(self).poll_flush(cx)
286    }
287
288    /// A convenience method for calling [`MultipartWrite::poll_complete`] on
289    /// [`Unpin`] writer types.
290    #[must_use = "futures do nothing unless polled"]
291    fn poll_complete_unpin(
292        &mut self,
293        cx: &mut Context<'_>,
294    ) -> Poll<Result<Self::Output, Self::Error>>
295    where
296        Self: Unpin,
297    {
298        Pin::new(self).poll_complete(cx)
299    }
300
301    /// A future that completes when a part has been fully processed into the
302    /// writer, including flushing.
303    fn send_part(&mut self, part: Part) -> SendPart<'_, Self, Part>
304    where
305        Self: Unpin,
306    {
307        SendPart::new(self, part)
308    }
309
310    /// Chain an asynchronous computation on the result of polling the writer for
311    /// completion.
312    fn then<T, E, Fut, F>(self, f: F) -> Then<Self, Fut, F>
313    where
314        F: FnMut(Result<Self::Output, Self::Error>) -> Fut,
315        Fut: Future<Output = Result<T, E>>,
316        E: From<Self::Error>,
317        Self: Sized,
318    {
319        assert_writer::<Part, Self::Ret, E, T, _>(Then::new(self, f))
320    }
321
322    /// Provide a part to this writer in the output of a future.
323    ///
324    /// The result is a new writer over the type `U` that passes each value
325    /// through the function `f`, resolving the output, and sending it to the
326    /// inner writer.
327    fn with<U, E, Fut, F>(self, f: F) -> With<Self, Part, Fut, F>
328    where
329        F: FnMut(U) -> Fut,
330        Fut: Future<Output = Result<Part, E>>,
331        E: From<Self::Error>,
332        Self: Sized,
333    {
334        assert_writer::<U, (), E, Self::Output, _>(With::new(self, f))
335    }
336}
337
338fn assert_writer<Part, R, E, T, Wr>(wr: Wr) -> Wr
339where
340    Wr: MultipartWrite<Part, Ret = R, Error = E, Output = T>,
341{
342    wr
343}