Merge pull request #443 from portgasd666/master

Added Future::flatten
poc-serde-support
Yoshua Wuyts 5 years ago committed by GitHub
commit 9a8805678e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,52 @@
use futures_core::ready;
use std::pin::Pin;
use crate::future::Future;
use crate::future::IntoFuture;
use crate::task::{Context, Poll};
#[derive(Debug)]
pub struct FlattenFuture<Fut1, Fut2> {
state: State<Fut1, Fut2>,
}
#[derive(Debug)]
enum State<Fut1, Fut2> {
First(Fut1),
Second(Fut2),
Empty,
}
impl<Fut1, Fut2> FlattenFuture<Fut1, Fut2> {
pub fn new(future: Fut1) -> FlattenFuture<Fut1, Fut2> {
FlattenFuture {
state: State::First(future),
}
}
}
impl<Fut1> Future for FlattenFuture<Fut1, <Fut1::Output as IntoFuture>::Future>
where
Fut1: Future,
Fut1::Output: IntoFuture,
{
type Output = <Fut1::Output as IntoFuture>::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let Self { state } = unsafe { self.get_unchecked_mut() };
loop {
match state {
State::First(fut1) => {
let fut2 = ready!(unsafe { Pin::new_unchecked(fut1) }.poll(cx)).into_future();
*state = State::Second(fut2);
}
State::Second(fut2) => {
let v = ready!(unsafe { Pin::new_unchecked(fut2) }.poll(cx));
*state = State::Empty;
return Poll::Ready(v);
}
State::Empty => panic!("polled a completed future"),
}
}
}
}

@ -1,11 +1,14 @@
cfg_unstable! { cfg_unstable! {
mod delay; mod delay;
mod flatten;
mod race; mod race;
mod try_race; mod try_race;
use std::time::Duration; use std::time::Duration;
use delay::DelayFuture; use delay::DelayFuture;
use flatten::FlattenFuture;
use crate::future::IntoFuture;
use race::Race; use race::Race;
use try_race::TryRace; use try_race::TryRace;
} }
@ -150,6 +153,30 @@ extension_trait! {
DelayFuture::new(self, dur) DelayFuture::new(self, dur)
} }
/// Flatten out the execution of this future when the result itself
/// can be converted into another future.
///
/// # Examples
///
/// ```
/// # async_std::task::block_on(async {
/// use async_std::prelude::*;
///
/// let nested_future = async { async { 1 } };
/// let future = nested_future.flatten();
/// assert_eq!(future.await, 1);
/// # })
/// ```
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
fn flatten(self) -> impl Future<Output = <<Self as Future>::Output as IntoFuture>::Output> [FlattenFuture<Self, <<Self as Future>::Output as IntoFuture>::Future>]
where
Self: Future + Sized,
<Self as Future>::Output: IntoFuture
{
FlattenFuture::new(self)
}
#[doc = r#" #[doc = r#"
Waits for one of two similarly-typed futures to complete. Waits for one of two similarly-typed futures to complete.

Loading…
Cancel
Save