1use std::{
2 pin::Pin,
3 task::{self, Poll},
4};
5
6use futures_core::ready;
7use pin_project_lite::pin_project;
8
9use crate::{actor::Actor, fut::ActorFuture};
10
11pin_project! {
12 #[project = ThenProj]
17 #[derive(Debug)]
18 #[must_use = "futures do nothing unless polled"]
19 pub enum Then<A, B, F> {
20 First {
21 #[pin]
22 fut1: A,
23 data: Option<F>,
24 },
25 Second {
26 #[pin]
27 fut2: B
28 },
29 Empty,
30 }
31}
32
33pub(super) fn new<A, B, F, Act>(future: A, f: F) -> Then<A, B, F>
34where
35 A: ActorFuture<Act>,
36 B: ActorFuture<Act>,
37 Act: Actor,
38{
39 Then::First {
40 fut1: future,
41 data: Some(f),
42 }
43}
44
45impl<A, B, F, Act> ActorFuture<Act> for Then<A, B, F>
46where
47 A: ActorFuture<Act>,
48 B: ActorFuture<Act>,
49 F: FnOnce(A::Output, &mut Act, &mut Act::Context) -> B,
50 Act: Actor,
51{
52 type Output = B::Output;
53
54 fn poll(
55 mut self: Pin<&mut Self>,
56 act: &mut Act,
57 ctx: &mut Act::Context,
58 task: &mut task::Context<'_>,
59 ) -> Poll<B::Output> {
60 match self.as_mut().project() {
61 ThenProj::First { fut1, data } => {
62 let output = ready!(fut1.poll(act, ctx, task));
63 let data = data.take().unwrap();
64 let fut2 = data(output, act, ctx);
65 self.set(Then::Second { fut2 });
66 self.poll(act, ctx, task)
67 }
68 ThenProj::Second { fut2 } => {
69 let res = ready!(fut2.poll(act, ctx, task));
70 self.set(Then::Empty);
71 Poll::Ready(res)
72 }
73 ThenProj::Empty => panic!("ActorFuture polled after finish"),
74 }
75 }
76}