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}