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}