diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-08-28 21:15:30 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-08-28 22:54:38 +0200 |
| commit | 3763baf8fa4cf332a81214eb1610afdaf5173824 (patch) | |
| tree | 1be543562d249a8ab77cf93b4382970c51a91f55 /embassy-futures | |
| parent | 1ee2dfa03e6d3578ffaac810b49b726e7da9cf36 (diff) | |
futures: add select_slice, rename select_all to select_array.
Diffstat (limited to 'embassy-futures')
| -rw-r--r-- | embassy-futures/README.md | 3 | ||||
| -rw-r--r-- | embassy-futures/src/select.rs | 62 |
2 files changed, 57 insertions, 8 deletions
diff --git a/embassy-futures/README.md b/embassy-futures/README.md index 971f4c835..3810bcafd 100644 --- a/embassy-futures/README.md +++ b/embassy-futures/README.md | |||
| @@ -5,5 +5,6 @@ Utilities for working with futures: | |||
| 5 | - [`select`](select::select) - waiting for one out of two futures to complete. | 5 | - [`select`](select::select) - waiting for one out of two futures to complete. |
| 6 | - [`select3`](select::select3) - waiting for one out of three futures to complete. | 6 | - [`select3`](select::select3) - waiting for one out of three futures to complete. |
| 7 | - [`select4`](select::select4) - waiting for one out of four futures to complete. | 7 | - [`select4`](select::select4) - waiting for one out of four futures to complete. |
| 8 | - [`select_all`](select::select_all) - waiting for one future in a list of futures to complete. | 8 | - [`select_array`](select::select_array) - waiting for one future in an array of futures to complete. |
| 9 | - [`select_slice`](select::select_slice) - waiting for one future in a slice of futures to complete. | ||
| 9 | - [`yield_now`](yield_now::yield_now) - yielding the current task. | 10 | - [`yield_now`](yield_now::yield_now) - yielding the current task. |
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"] |
| 192 | pub struct SelectAll<Fut, const N: usize> { | 192 | pub 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. |
| 205 | pub fn select_all<Fut: Future, const N: usize>(arr: [Fut; N]) -> SelectAll<Fut, N> { | 205 | pub 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 | ||
| 210 | impl<Fut: Future, const N: usize> Future for SelectAll<Fut, N> { | 210 | impl<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"] | ||
| 240 | pub 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. | ||
| 253 | pub fn select_slice<'a, Fut: Future>(slice: &'a mut [Fut]) -> SelectSlice<'a, Fut> { | ||
| 254 | assert!(!slice.is_empty()); | ||
| 255 | SelectSlice { inner: slice } | ||
| 256 | } | ||
| 257 | |||
| 258 | impl<'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> { |
