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