actix/fut/try_future/mod.rs
1use std::{
2 pin::Pin,
3 task::{Context, Poll},
4};
5
6use crate::{actor::Actor, fut::future::ActorFuture};
7
8mod and_then;
9mod map_err;
10mod map_ok;
11
12pub use and_then::AndThen;
13pub use map_err::MapErr;
14pub use map_ok::MapOk;
15
16mod private_try_act_future {
17 use super::{Actor, ActorFuture};
18
19 pub trait Sealed<A> {}
20
21 impl<A, F, T, E> Sealed<A> for F
22 where
23 A: Actor,
24 F: ?Sized + ActorFuture<A, Output = Result<T, E>>,
25 {
26 }
27}
28
29/// A convenience for actor futures that return `Result` values that includes
30/// a variety of adapters tailored to such actor futures.
31pub trait ActorTryFuture<A: Actor>: ActorFuture<A> + private_try_act_future::Sealed<A> {
32 /// The type of successful values yielded by this actor future
33 type Ok;
34
35 /// The type of failures yielded by this actor future
36 type Error;
37
38 /// Poll this `ActorTryFuture` as if it were a `ActorFuture`.
39 ///
40 /// This method is a stopgap for a compiler limitation that prevents us from
41 /// directly inheriting from the `ActorFuture` trait; in the actor future it
42 /// won't be needed.
43 fn try_poll(
44 self: Pin<&mut Self>,
45 srv: &mut A,
46 ctx: &mut A::Context,
47 task: &mut Context<'_>,
48 ) -> Poll<Result<Self::Ok, Self::Error>>;
49}
50
51impl<A, F, T, E> ActorTryFuture<A> for F
52where
53 A: Actor,
54 F: ActorFuture<A, Output = Result<T, E>> + ?Sized,
55{
56 type Ok = T;
57 type Error = E;
58
59 fn try_poll(
60 self: Pin<&mut Self>,
61 srv: &mut A,
62 ctx: &mut A::Context,
63 task: &mut Context<'_>,
64 ) -> Poll<F::Output> {
65 self.poll(srv, ctx, task)
66 }
67}
68
69/// Adapters specific to [`Result`]-returning actor futures
70pub trait ActorTryFutureExt<A: Actor>: ActorTryFuture<A> {
71 /// Executes another actor future after this one resolves successfully.
72 /// The success value is passed to a closure to create this subsequent
73 /// actor future.
74 ///
75 /// The provided closure `f` will only be called if this actor future is
76 /// resolved to an [`Ok`]. If this actor future resolves to an [`Err`],
77 /// panics, or is dropped, then the provided closure will never
78 /// be invoked. The [`Error`](ActorTryFuture::Error) type of
79 /// this actor future and the actor future returned by `f` have to match.
80 ///
81 /// Note that this method consumes the actor future it is called on and
82 /// returns a wrapped version of it.
83 fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
84 where
85 F: FnOnce(Self::Ok, &mut A, &mut A::Context) -> Fut,
86 Fut: ActorTryFuture<A, Error = Self::Error>,
87 Self: Sized,
88 {
89 and_then::new(self, f)
90 }
91
92 /// Maps this actor future's success value to a different value.
93 ///
94 /// This method can be used to change the [`Ok`](ActorTryFuture::Ok) type
95 /// of the actor future into a different type. It is similar to the
96 /// [`Result::map`] method. You can use this method to chain along a
97 /// computation once the actor future has been resolved.
98 ///
99 /// The provided closure `f` will only be called if this actor future is
100 /// resolved to an [`Ok`]. If it resolves to an [`Err`], panics, or is
101 /// dropped, then the provided closure will never be invoked.
102 ///
103 /// Note that this method consumes the actor future it is called on and
104 /// returns a wrapped version of it.
105 fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
106 where
107 F: FnOnce(Self::Ok, &mut A, &mut A::Context) -> T,
108 Self: Sized,
109 {
110 MapOk::new(self, f)
111 }
112
113 /// Maps this actor future's error value to a different value.
114 ///
115 /// This method can be used to change the [`Error`](ActorTryFuture::Error)
116 /// type of the actor future into a different type. It is similar to the
117 /// [`Result::map_err`] method.
118 ///
119 /// The provided closure `f` will only be called if this actor future is
120 /// resolved to an [`Err`]. If it resolves to an [`Ok`], panics, or is
121 /// dropped, then the provided closure will never be invoked.
122 ///
123 /// Note that this method consumes the actor future it is called on and
124 /// returns a wrapped version of it.
125 fn map_err<T, F>(self, f: F) -> MapErr<Self, F>
126 where
127 F: FnOnce(Self::Error, &mut A, &mut A::Context) -> T,
128 Self: Sized,
129 {
130 MapErr::new(self, f)
131 }
132}
133
134impl<A, F> ActorTryFutureExt<A> for F
135where
136 A: Actor,
137 F: ActorTryFuture<A> + ?Sized,
138{
139}