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! { | 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