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