Skip to content

Commit 5e27297

Browse files
committed
implement Future::select
Signed-off-by: Yoshua Wuyts <[email protected]>
1 parent 8bce638 commit 5e27297

File tree

2 files changed

+66
-5
lines changed

2 files changed

+66
-5
lines changed

src/future/future.rs renamed to src/future/future/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
mod select;
2+
3+
use select::Select;
4+
15
extension_trait! {
26
use std::pin::Pin;
37
use std::ops::{Deref, DerefMut};
@@ -99,7 +103,6 @@ extension_trait! {
99103
}
100104

101105
pub trait FutureExt: std::future::Future {
102-
103106
#[doc = r#"
104107
Waits for either one of several similarly-typed futures to complete.
105108
@@ -117,9 +120,9 @@ extension_trait! {
117120
# Examples
118121
119122
```
120-
#![feature(async_await)]
121123
# futures::executor::block_on(async {
122-
use futures::future;
124+
use async_std::prelude::*;
125+
use async_std::future;
123126
124127
let a = future::pending();
125128
let b = future::ready(1u8);
@@ -130,8 +133,12 @@ extension_trait! {
130133
# });
131134
```
132135
"#]
133-
fn select(&mut self) -> () {
134-
()
136+
fn select<F>(self, other: F) -> Select<Self, F>
137+
where
138+
Self: Sized,
139+
F: Future<Output = Self::Output>,
140+
{
141+
Select::new(self, other)
135142
}
136143
}
137144

src/future/future/select.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::pin::Pin;
2+
3+
use pin_project_lite::pin_project;
4+
use async_macros::MaybeDone;
5+
6+
use crate::future::Future;
7+
// use crate::future::MaybeDone;
8+
use crate::task::{Context, Poll};
9+
10+
pin_project! {
11+
#[allow(missing_docs)]
12+
#[allow(missing_debug_implementations)]
13+
pub struct Select<L, R> where L: Future, R: Future<Output = L::Output> {
14+
#[pin] left: MaybeDone<L>,
15+
#[pin] right: MaybeDone<R>,
16+
}
17+
}
18+
19+
impl<L, R> Select<L, R>
20+
where
21+
L: Future,
22+
R: Future<Output = L::Output>,
23+
{
24+
pub(crate) fn new(left: L, right: R) -> Self {
25+
Self {
26+
left: MaybeDone::new(left),
27+
right: MaybeDone::new(right),
28+
}
29+
}
30+
}
31+
32+
impl<L, R> Future for Select<L, R>
33+
where
34+
L: Future,
35+
R: Future<Output = L::Output>,
36+
{
37+
type Output = L::Output;
38+
39+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
40+
let this = self.project();
41+
42+
let mut left = this.left;
43+
if Future::poll(Pin::new(&mut left), cx).is_ready() {
44+
return Poll::Ready(left.take().unwrap());
45+
}
46+
47+
let mut right = this.right;
48+
if Future::poll(Pin::new(&mut right), cx).is_ready() {
49+
return Poll::Ready(right.take().unwrap());
50+
}
51+
52+
Poll::Pending
53+
}
54+
}

0 commit comments

Comments
 (0)