multipart_write/write/
fold_ret.rs1use crate::{FusedMultipartWrite, MultipartWrite};
2
3use futures_core::ready;
4use std::fmt::{self, Debug, Formatter};
5use std::pin::Pin;
6use std::task::{Context, Poll};
7
8pin_project_lite::pin_project! {
9 #[must_use = "futures do nothing unless polled"]
11 pub struct FoldRet<Wr, F, T> {
12 #[pin]
13 writer: Wr,
14 acc: Option<T>,
15 f: F,
16 }
17}
18
19impl<Wr, F, T> FoldRet<Wr, F, T> {
20 pub(super) fn new(writer: Wr, id: T, f: F) -> Self {
21 Self {
22 writer,
23 acc: Some(id),
24 f,
25 }
26 }
27
28 pub fn get_ref(&self) -> &Wr {
30 &self.writer
31 }
32
33 pub fn get_mut(&mut self) -> &mut Wr {
37 &mut self.writer
38 }
39
40 pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut Wr> {
44 self.project().writer
45 }
46}
47
48impl<Wr, F, T, Part> FusedMultipartWrite<Part> for FoldRet<Wr, F, T>
49where
50 Wr: FusedMultipartWrite<Part>,
51 F: FnMut(T, &Wr::Ret) -> T,
52{
53 fn is_terminated(&self) -> bool {
54 self.writer.is_terminated()
55 }
56}
57
58impl<Wr, F, T, Part> MultipartWrite<Part> for FoldRet<Wr, F, T>
59where
60 Wr: MultipartWrite<Part>,
61 F: FnMut(T, &Wr::Ret) -> T,
62{
63 type Ret = Wr::Ret;
64 type Output = (T, Wr::Output);
65 type Error = Wr::Error;
66
67 fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
68 self.project().writer.poll_ready(cx)
69 }
70
71 fn start_send(self: Pin<&mut Self>, part: Part) -> Result<Self::Ret, Self::Error> {
72 let mut this = self.project();
73 let ret = this.writer.as_mut().start_send(part)?;
74 let new_acc = this.acc.take().map(|acc| (this.f)(acc, &ret));
75 *this.acc = new_acc;
76 Ok(ret)
77 }
78
79 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
80 self.project().writer.poll_flush(cx)
81 }
82
83 fn poll_complete(
84 self: Pin<&mut Self>,
85 cx: &mut Context<'_>,
86 ) -> Poll<Result<Self::Output, Self::Error>> {
87 let mut this = self.project();
88 let output = ready!(this.writer.as_mut().poll_complete(cx))?;
89 let acc = this.acc.take().expect("polled FoldRet after completion");
90 Poll::Ready(Ok((acc, output)))
91 }
92}
93
94impl<Wr, F, T> Debug for FoldRet<Wr, F, T>
95where
96 Wr: Debug,
97 T: Debug,
98{
99 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
100 f.debug_struct("FoldRet")
101 .field("writer", &self.writer)
102 .field("acc", &self.acc)
103 .field("f", &"F")
104 .finish()
105 }
106}