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