aboutsummaryrefslogtreecommitdiff
path: root/embassy-futures/src/select.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-futures/src/select.rs')
-rw-r--r--embassy-futures/src/select.rs62
1 files changed, 55 insertions, 7 deletions
diff --git a/embassy-futures/src/select.rs b/embassy-futures/src/select.rs
index 53fa1da61..facc2f60b 100644
--- a/embassy-futures/src/select.rs
+++ b/embassy-futures/src/select.rs
@@ -186,28 +186,76 @@ where
186 186
187// ==================================================================== 187// ====================================================================
188 188
189/// Future for the [`select_all`] function. 189/// Future for the [`select_array`] function.
190#[derive(Debug)] 190#[derive(Debug)]
191#[must_use = "futures do nothing unless you `.await` or poll them"] 191#[must_use = "futures do nothing unless you `.await` or poll them"]
192pub struct SelectAll<Fut, const N: usize> { 192pub struct SelectArray<Fut, const N: usize> {
193 inner: [Fut; N], 193 inner: [Fut; N],
194} 194}
195 195
196/// Creates a new future which will select over a list of futures. 196/// Creates a new future which will select over an array of futures.
197/// 197///
198/// The returned future will wait for any future within `iter` to be ready. Upon 198/// The returned future will wait for any future to be ready. Upon
199/// completion the item resolved will be returned, along with the index of the 199/// completion the item resolved will be returned, along with the index of the
200/// future that was ready. 200/// future that was ready.
201/// 201///
202/// # Panics 202/// # Panics
203/// 203///
204/// This function will panic if the array specified contains no items. 204/// This function will panic if the array specified contains no items.
205pub fn select_all<Fut: Future, const N: usize>(arr: [Fut; N]) -> SelectAll<Fut, N> { 205pub fn select_array<Fut: Future, const N: usize>(arr: [Fut; N]) -> SelectArray<Fut, N> {
206 assert!(N > 0); 206 assert!(N > 0);
207 SelectAll { inner: arr } 207 SelectArray { inner: arr }
208} 208}
209 209
210impl<Fut: Future, const N: usize> Future for SelectAll<Fut, N> { 210impl<Fut: Future, const N: usize> Future for SelectArray<Fut, N> {
211 type Output = (Fut::Output, usize);
212
213 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
214 // Safety: Since `self` is pinned, `inner` cannot move. Since `inner` cannot move,
215 // its elements also cannot move. Therefore it is safe to access `inner` and pin
216 // references to the contained futures.
217 let item = unsafe {
218 self.get_unchecked_mut()
219 .inner
220 .iter_mut()
221 .enumerate()
222 .find_map(|(i, f)| match Pin::new_unchecked(f).poll(cx) {
223 Poll::Pending => None,
224 Poll::Ready(e) => Some((i, e)),
225 })
226 };
227
228 match item {
229 Some((idx, res)) => Poll::Ready((res, idx)),
230 None => Poll::Pending,
231 }
232 }
233}
234
235// ====================================================================
236
237/// Future for the [`select_slice`] function.
238#[derive(Debug)]
239#[must_use = "futures do nothing unless you `.await` or poll them"]
240pub struct SelectSlice<'a, Fut> {
241 inner: &'a mut [Fut],
242}
243
244/// Creates a new future which will select over a slice of futures.
245///
246/// The returned future will wait for any future to be ready. Upon
247/// completion the item resolved will be returned, along with the index of the
248/// future that was ready.
249///
250/// # Panics
251///
252/// This function will panic if the slice specified contains no items.
253pub fn select_slice<'a, Fut: Future>(slice: &'a mut [Fut]) -> SelectSlice<'a, Fut> {
254 assert!(!slice.is_empty());
255 SelectSlice { inner: slice }
256}
257
258impl<'a, Fut: Future> Future for SelectSlice<'a, Fut> {
211 type Output = (Fut::Output, usize); 259 type Output = (Fut::Output, usize);
212 260
213 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 261 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {