mirror of
https://github.com/async-rs/async-std.git
synced 2025-03-28 20:16:41 +00:00
commit
9a8805678e
2 changed files with 79 additions and 0 deletions
52
src/future/future/flatten.rs
Normal file
52
src/future/future/flatten.rs
Normal file
|
@ -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…
Reference in a new issue