forked from mirror/async-std
Replace select!/try_select! with Future::{race,try_race} (#405)
* init Future::select Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * implement Future::select Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * try_select Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * fixes Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * works Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * pass clippy Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * please clippy Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * implement feedback from stjepan Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * rename select to race Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * fmt Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com>poc-serde-support
parent
3a2e6d5b92
commit
735fa6954e
@ -0,0 +1,57 @@
|
|||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
use async_macros::MaybeDone;
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
|
use crate::task::{Context, Poll};
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
pin_project! {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[allow(missing_debug_implementations)]
|
||||||
|
pub struct Race<L, R>
|
||||||
|
where
|
||||||
|
L: Future,
|
||||||
|
R: Future<Output = L::Output>
|
||||||
|
{
|
||||||
|
#[pin] left: MaybeDone<L>,
|
||||||
|
#[pin] right: MaybeDone<R>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<L, R> Race<L, R>
|
||||||
|
where
|
||||||
|
L: Future,
|
||||||
|
R: Future<Output = L::Output>,
|
||||||
|
{
|
||||||
|
pub(crate) fn new(left: L, right: R) -> Self {
|
||||||
|
Self {
|
||||||
|
left: MaybeDone::new(left),
|
||||||
|
right: MaybeDone::new(right),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<L, R> Future for Race<L, R>
|
||||||
|
where
|
||||||
|
L: Future,
|
||||||
|
R: Future<Output = L::Output>,
|
||||||
|
{
|
||||||
|
type Output = L::Output;
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let this = self.project();
|
||||||
|
|
||||||
|
let mut left = this.left;
|
||||||
|
if Future::poll(Pin::new(&mut left), cx).is_ready() {
|
||||||
|
return Poll::Ready(left.take().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut right = this.right;
|
||||||
|
if Future::poll(Pin::new(&mut right), cx).is_ready() {
|
||||||
|
return Poll::Ready(right.take().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
use async_macros::MaybeDone;
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
|
use crate::task::{Context, Poll};
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
pin_project! {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[allow(missing_debug_implementations)]
|
||||||
|
pub struct TryRace<L, R>
|
||||||
|
where
|
||||||
|
L: Future,
|
||||||
|
R: Future<Output = L::Output>
|
||||||
|
{
|
||||||
|
#[pin] left: MaybeDone<L>,
|
||||||
|
#[pin] right: MaybeDone<R>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<L, R> TryRace<L, R>
|
||||||
|
where
|
||||||
|
L: Future,
|
||||||
|
R: Future<Output = L::Output>,
|
||||||
|
{
|
||||||
|
pub(crate) fn new(left: L, right: R) -> Self {
|
||||||
|
Self {
|
||||||
|
left: MaybeDone::new(left),
|
||||||
|
right: MaybeDone::new(right),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<L, R, T, E> Future for TryRace<L, R>
|
||||||
|
where
|
||||||
|
L: Future<Output = Result<T, E>>,
|
||||||
|
R: Future<Output = L::Output>,
|
||||||
|
{
|
||||||
|
type Output = L::Output;
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let this = self.project();
|
||||||
|
let mut left_errored = false;
|
||||||
|
|
||||||
|
// Check if the left future is ready & successful. Continue if not.
|
||||||
|
let mut left = this.left;
|
||||||
|
if Future::poll(Pin::new(&mut left), cx).is_ready() {
|
||||||
|
if left.as_ref().output().unwrap().is_ok() {
|
||||||
|
return Poll::Ready(left.take().unwrap());
|
||||||
|
} else {
|
||||||
|
left_errored = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the right future is ready & successful. Return err if left
|
||||||
|
// future also resolved to err. Continue if not.
|
||||||
|
let mut right = this.right;
|
||||||
|
let is_ready = Future::poll(Pin::new(&mut right), cx).is_ready();
|
||||||
|
if is_ready && (right.as_ref().output().unwrap().is_ok() || left_errored) {
|
||||||
|
return Poll::Ready(right.take().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue