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