aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy/src/util/select.rs169
1 files changed, 169 insertions, 0 deletions
diff --git a/embassy/src/util/select.rs b/embassy/src/util/select.rs
index b3b03d81c..ccc50f117 100644
--- a/embassy/src/util/select.rs
+++ b/embassy/src/util/select.rs
@@ -2,6 +2,175 @@ use core::future::Future;
2use core::pin::Pin; 2use core::pin::Pin;
3use core::task::{Context, Poll}; 3use core::task::{Context, Poll};
4 4
5#[derive(Debug, Clone)]
6pub enum Either<A, B> {
7 First(A),
8 Second(B),
9}
10
11/// Wait for one of two futures to complete.
12///
13/// This function returns a new future which polls all the futures.
14/// When one of them completes, it will complete with its result value.
15///
16/// The other future is dropped.
17pub fn select<A, B>(a: A, b: B) -> Select<A, B>
18where
19 A: Future,
20 B: Future,
21{
22 Select { a, b }
23}
24
25/// Future for the [`select`] function.
26#[derive(Debug)]
27#[must_use = "futures do nothing unless you `.await` or poll them"]
28pub struct Select<A, B> {
29 a: A,
30 b: B,
31}
32
33impl<A: Unpin, B: Unpin> Unpin for Select<A, B> {}
34
35impl<A, B> Future for Select<A, B>
36where
37 A: Future,
38 B: Future,
39{
40 type Output = Either<A::Output, B::Output>;
41
42 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
43 let this = unsafe { self.get_unchecked_mut() };
44 let a = unsafe { Pin::new_unchecked(&mut this.a) };
45 let b = unsafe { Pin::new_unchecked(&mut this.b) };
46 if let Poll::Ready(x) = a.poll(cx) {
47 return Poll::Ready(Either::First(x));
48 }
49 if let Poll::Ready(x) = b.poll(cx) {
50 return Poll::Ready(Either::Second(x));
51 }
52 Poll::Pending
53 }
54}
55
56// ====================================================================
57
58#[derive(Debug, Clone)]
59pub enum Either3<A, B, C> {
60 First(A),
61 Second(B),
62 Third(C),
63}
64
65/// Same as [`select`], but with more futures.
66pub fn select3<A, B, C>(a: A, b: B, c: C) -> Select3<A, B, C>
67where
68 A: Future,
69 B: Future,
70 C: Future,
71{
72 Select3 { a, b, c }
73}
74
75/// Future for the [`select3`] function.
76#[derive(Debug)]
77#[must_use = "futures do nothing unless you `.await` or poll them"]
78pub struct Select3<A, B, C> {
79 a: A,
80 b: B,
81 c: C,
82}
83
84impl<A, B, C> Future for Select3<A, B, C>
85where
86 A: Future,
87 B: Future,
88 C: Future,
89{
90 type Output = Either3<A::Output, B::Output, C::Output>;
91
92 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
93 let this = unsafe { self.get_unchecked_mut() };
94 let a = unsafe { Pin::new_unchecked(&mut this.a) };
95 let b = unsafe { Pin::new_unchecked(&mut this.b) };
96 let c = unsafe { Pin::new_unchecked(&mut this.c) };
97 if let Poll::Ready(x) = a.poll(cx) {
98 return Poll::Ready(Either3::First(x));
99 }
100 if let Poll::Ready(x) = b.poll(cx) {
101 return Poll::Ready(Either3::Second(x));
102 }
103 if let Poll::Ready(x) = c.poll(cx) {
104 return Poll::Ready(Either3::Third(x));
105 }
106 Poll::Pending
107 }
108}
109
110// ====================================================================
111
112#[derive(Debug, Clone)]
113pub enum Either4<A, B, C, D> {
114 First(A),
115 Second(B),
116 Third(C),
117 Fourth(D),
118}
119
120/// Same as [`select`], but with more futures.
121pub fn select4<A, B, C, D>(a: A, b: B, c: C, d: D) -> Select4<A, B, C, D>
122where
123 A: Future,
124 B: Future,
125 C: Future,
126 D: Future,
127{
128 Select4 { a, b, c, d }
129}
130
131/// Future for the [`select4`] function.
132#[derive(Debug)]
133#[must_use = "futures do nothing unless you `.await` or poll them"]
134pub struct Select4<A, B, C, D> {
135 a: A,
136 b: B,
137 c: C,
138 d: D,
139}
140
141impl<A, B, C, D> Future for Select4<A, B, C, D>
142where
143 A: Future,
144 B: Future,
145 C: Future,
146 D: Future,
147{
148 type Output = Either4<A::Output, B::Output, C::Output, D::Output>;
149
150 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
151 let this = unsafe { self.get_unchecked_mut() };
152 let a = unsafe { Pin::new_unchecked(&mut this.a) };
153 let b = unsafe { Pin::new_unchecked(&mut this.b) };
154 let c = unsafe { Pin::new_unchecked(&mut this.c) };
155 let d = unsafe { Pin::new_unchecked(&mut this.d) };
156 if let Poll::Ready(x) = a.poll(cx) {
157 return Poll::Ready(Either4::First(x));
158 }
159 if let Poll::Ready(x) = b.poll(cx) {
160 return Poll::Ready(Either4::Second(x));
161 }
162 if let Poll::Ready(x) = c.poll(cx) {
163 return Poll::Ready(Either4::Third(x));
164 }
165 if let Poll::Ready(x) = d.poll(cx) {
166 return Poll::Ready(Either4::Fourth(x));
167 }
168 Poll::Pending
169 }
170}
171
172// ====================================================================
173
5/// Future for the [`select_all`] function. 174/// Future for the [`select_all`] function.
6#[derive(Debug)] 175#[derive(Debug)]
7#[must_use = "futures do nothing unless you `.await` or poll them"] 176#[must_use = "futures do nothing unless you `.await` or poll them"]