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