forked from mirror/async-std
		
	
						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! { | ||||
|     mod delay; | ||||
|     mod flatten; | ||||
|     mod race; | ||||
|     mod try_race; | ||||
| 
 | ||||
|     use std::time::Duration; | ||||
| 
 | ||||
|     use delay::DelayFuture; | ||||
|     use flatten::FlattenFuture; | ||||
|     use crate::future::IntoFuture; | ||||
|     use race::Race; | ||||
|     use try_race::TryRace; | ||||
| } | ||||
|  | @ -150,6 +153,30 @@ extension_trait! { | |||
|             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#" | ||||
|             Waits for one of two similarly-typed futures to complete. | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue