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