actix_utils/future/
either.rs1use core::{
4    future::Future,
5    pin::Pin,
6    task::{Context, Poll},
7};
8
9use pin_project_lite::pin_project;
10
11pin_project! {
12    #[project = EitherProj]
29    #[derive(Debug, Clone)]
30    pub enum Either<L, R> {
31        #[allow(missing_docs)]
33        Left { #[pin] value: L },
34
35        #[allow(missing_docs)]
37        Right { #[pin] value: R },
38    }
39}
40
41impl<L, R> Either<L, R> {
42    #[inline]
44    pub fn left(value: L) -> Either<L, R> {
45        Either::Left { value }
46    }
47
48    #[inline]
50    pub fn right(value: R) -> Either<L, R> {
51        Either::Right { value }
52    }
53}
54
55impl<T> Either<T, T> {
56    #[inline]
58    pub fn into_inner(self) -> T {
59        match self {
60            Either::Left { value } => value,
61            Either::Right { value } => value,
62        }
63    }
64}
65
66impl<L, R> Future for Either<L, R>
67where
68    L: Future,
69    R: Future<Output = L::Output>,
70{
71    type Output = L::Output;
72
73    #[inline]
74    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
75        match self.project() {
76            EitherProj::Left { value } => value.poll(cx),
77            EitherProj::Right { value } => value.poll(cx),
78        }
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85    use crate::future::{ready, Ready};
86
87    #[actix_rt::test]
88    async fn test_either() {
89        let res = Either::<_, Ready<usize>>::left(ready(42));
90        assert_eq!(res.await, 42);
91
92        let res = Either::<Ready<usize>, _>::right(ready(43));
93        assert_eq!(res.await, 43);
94    }
95}