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};
6
7use futures_core::future::Future;
8use std::pin::Pin;
9use std::task::{Context, Poll};
10
11pub use crate::MultipartWrite;
12
13mod bootstrapped;
14pub use bootstrapped::Bootstrapped;
15
16mod buffered;
17pub use buffered::Buffered;
18
19mod complete;
20pub use complete::Complete;
21
22mod fanout;
23pub use fanout::Fanout;
24
25mod feed;
26pub use feed::Feed;
27
28mod fold_ret;
29pub use fold_ret::FoldRet;
30
31mod flush;
32pub use flush::Flush;
33
34mod map;
35pub use map::Map;
36
37mod map_err;
38pub use map_err::MapErr;
39
40mod map_part;
41pub use map_part::MapPart;
42
43mod map_ret;
44pub use map_ret::MapRet;
45
46mod send_part;
47pub use send_part::SendPart;
48
49mod then;
50pub use then::Then;
51
52mod with;
53pub use with::With;
54
55impl<Wr: MultipartWrite<Part>, Part> MultipartWriteExt<Part> for Wr {}
56
57/// An extension trait for `MultipartWrite`rs providing a variety of convenient
58/// combinator functions.
59pub trait MultipartWriteExt<Part>: MultipartWrite<Part> {
60    /// Returns a writer wrapping this one and having the property that a call to
61    /// `poll_ready` will create `Self` if missing.
62    ///
63    /// The value `S` and closure `F` determine how this is done.  If a multipart
64    /// write is not left in a reusable state after `poll_complete`, this adapter
65    /// can be used to make a writer more than one-time-use where it otherwise
66    /// would not be.
67    fn bootstrapped<S, F, Fut>(self, s: S, f: F) -> Bootstrapped<Self, S, F, Fut>
68    where
69        F: FnMut(&mut S) -> Fut,
70        Fut: Future<Output = Result<Option<Self>, Self::Error>>,
71        Self: Sized,
72    {
73        Bootstrapped::new(self, s, f)
74    }
75
76    /// Wrap this writer in a `Box`, pinning it.
77    fn boxed<'a>(self) -> BoxMultipartWrite<'a, Part, Self::Ret, Self::Output, Self::Error>
78    where
79        Self: Sized + Send + 'a,
80    {
81        Box::pin(self)
82    }
83
84    /// Wrap this writer in a `Box`, pinning it.
85    ///
86    /// Similar to `boxed` but without the `Send` requirement.
87    fn boxed_local<'a>(
88        self,
89    ) -> LocalBoxMultipartWrite<'a, Part, Self::Ret, Self::Output, Self::Error>
90    where
91        Self: Sized + 'a,
92    {
93        Box::pin(self)
94    }
95
96    /// Adds a fixed size buffer to the current writer.
97    ///
98    /// The resulting `MultipartWrite` will buffer up to `capacity` items when
99    /// the underlying writer is not able to accept new parts.
100    fn buffered(self, capacity: impl Into<Option<usize>>) -> Buffered<Self, Part>
101    where
102        Self: Sized,
103    {
104        Buffered::new(self, capacity.into().unwrap_or_default())
105    }
106
107    /// A future that runs this writer to completion, returning the associated
108    /// output.
109    fn complete(&mut self) -> Complete<'_, Self, Part>
110    where
111        Self: Unpin,
112    {
113        Complete::new(self)
114    }
115
116    /// Fanout the part to multiple writers.
117    ///
118    /// This adapter clones each incoming part and forwards it to both writers.
119    fn fanout<U>(self, other: U) -> Fanout<Self, U, Part>
120    where
121        Part: Clone,
122        U: MultipartWrite<Part, Error = Self::Error>,
123        Self: Sized,
124    {
125        Fanout::new(self, other)
126    }
127
128    /// A future that completes after the given part has been received by the
129    /// writer.
130    ///
131    /// Unlike `write`, the returned future does not flush the writer.  It is the
132    /// caller's responsibility to ensure all pending items are processed, which
133    /// can be done with `flush` or `complete`.
134    fn feed(&mut self, part: Part) -> Feed<'_, Self, Part>
135    where
136        Self: Unpin,
137    {
138        Feed::new(self, part)
139    }
140
141    /// A future that completes when the underlying writer has been flushed.
142    fn flush(&mut self) -> Flush<'_, Self, Part>
143    where
144        Self: Unpin,
145    {
146        Flush::new(self)
147    }
148
149    /// Accumulate this writer's returned values, returning a new multipart
150    /// writer that pairs the underlying writer's output with the
151    /// result of the accumulating function.
152    fn fold_ret<T, F>(self, id: T, f: F) -> FoldRet<Self, F, T>
153    where
154        F: FnMut(T, &Self::Ret) -> T,
155        Self: Sized,
156    {
157        FoldRet::new(self, id, f)
158    }
159
160    /// Map this writer's output type to a different type, returning a new
161    /// multipart writer with the given output type.
162    fn map<U, F>(self, f: F) -> Map<Self, F>
163    where
164        F: FnMut(Self::Output) -> U,
165        Self: Sized,
166    {
167        Map::new(self, f)
168    }
169
170    /// Map this writer's error type to a different value, returning a new
171    /// multipart writer with the given error type.
172    fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
173    where
174        F: FnMut(Self::Error) -> E,
175        Self: Sized,
176    {
177        MapErr::new(self, f)
178    }
179
180    /// Pre-compose the underlying writer with a function that transforms a
181    /// the input part type.
182    fn map_part<U, F>(self, f: F) -> MapPart<Self, F>
183    where
184        F: FnMut(U) -> Result<Part, Self::Error>,
185        Self: MultipartWrite<Part> + Sized,
186    {
187        MapPart::new(self, f)
188    }
189
190    /// Map this writer's return type to a different value, returning a new
191    /// multipart writer with the given return type.
192    fn map_ret<U, F>(self, f: F) -> MapRet<Self, F>
193    where
194        F: FnMut(Self::Ret) -> U,
195        Self: Sized,
196    {
197        MapRet::new(self, f)
198    }
199
200    /// A convenience method for calling [`poll_ready`] on [`Unpin`] writer types.
201    ///
202    /// [`poll_ready`]: super::MultipartWrite::poll_ready
203    #[must_use = "futures do nothing unless polled"]
204    fn poll_ready_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
205    where
206        Self: Unpin,
207    {
208        Pin::new(self).poll_ready(cx)
209    }
210
211    /// A convenience method for calling [`poll_flush`] on [`Unpin`] writer types.
212    ///
213    /// [`poll_flush`]: super::MultipartWrite::poll_flush
214    #[must_use = "futures do nothing unless polled"]
215    fn poll_flush_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
216    where
217        Self: Unpin,
218    {
219        Pin::new(self).poll_flush(cx)
220    }
221
222    /// A convenience method for calling [`poll_complete`] on [`Unpin`] writer types.
223    ///
224    /// [`poll_complete`]: super::MultipartWrite::poll_complete
225    #[must_use = "futures do nothing unless polled"]
226    fn poll_complete_unpin(
227        &mut self,
228        cx: &mut Context<'_>,
229    ) -> Poll<Result<Self::Output, Self::Error>>
230    where
231        Self: Unpin,
232    {
233        Pin::new(self).poll_complete(cx)
234    }
235
236    /// A future that completes when a part has been fully processed into the
237    /// writer, including flushing.
238    fn send_part(&mut self, part: Part) -> SendPart<'_, Self, Part>
239    where
240        Self: Unpin,
241    {
242        SendPart::new(self, part)
243    }
244
245    /// Chain a computation on the output of a writer.
246    fn then<U, F, Fut>(self, f: F) -> Then<Self, F, Fut>
247    where
248        F: FnMut(Self::Output) -> Fut,
249        Fut: Future<Output = U>,
250        Self: Sized,
251    {
252        Then::new(self, f)
253    }
254
255    /// Composes a function in front of the `MultipartWrite`.
256    ///
257    /// This adapter produces a new `MultipartWrite` by passing each part through
258    /// the given function `f` before sending it to `self`.
259    fn with<U, Fut, F, E>(self, f: F) -> With<Self, Part, U, Fut, F>
260    where
261        F: FnMut(U) -> Fut,
262        Fut: Future<Output = Result<Part, E>>,
263        E: From<Self::Error>,
264        Self: Sized,
265    {
266        With::new(self, f)
267    }
268}