File tree Expand file tree Collapse file tree 2 files changed +73
-0
lines changed Expand file tree Collapse file tree 2 files changed +73
-0
lines changed Original file line number Diff line number Diff line change 11cfg_unstable ! {
22 mod delay;
3+ mod flatten;
34
45 use std:: time:: Duration ;
56
67 use delay:: DelayFuture ;
8+ use flatten:: FlattenFuture ;
9+ use crate :: future:: IntoFuture ;
710}
811
912extension_trait ! {
@@ -129,6 +132,30 @@ extension_trait! {
129132 {
130133 DelayFuture :: new( self , dur)
131134 }
135+
136+ /// Flatten out the execution of this future when the result itself
137+ /// can be converted into another future.
138+ ///
139+ /// # Examples
140+ ///
141+ /// ```
142+ /// # async_std::task::block_on(async {
143+ /// use async_std::prelude::*;
144+ ///
145+ /// let nested_future = async { async { 1 } };
146+ /// let future = nested_future.flatten();
147+ /// assert_eq!(future.await, 1);
148+ /// # })
149+ /// ```
150+ #[ cfg_attr( feature = "docs" , doc( cfg( unstable) ) ) ]
151+ #[ cfg( any( feature = "unstable" , feature = "docs" ) ) ]
152+ fn flatten( self ) -> FlattenFuture <Self , <Self :: Output as IntoFuture >:: Future >
153+ where
154+ Self : Future + Sized ,
155+ Self :: Output : IntoFuture
156+ {
157+ FlattenFuture :: new( self )
158+ }
132159 }
133160
134161 impl <F : Future + Unpin + ?Sized > Future for Box <F > {
Original file line number Diff line number Diff line change 1+ use futures_core:: ready;
2+ use std:: pin:: Pin ;
3+
4+ use crate :: future:: Future ;
5+ use crate :: future:: IntoFuture ;
6+ use crate :: task:: { Context , Poll } ;
7+
8+ #[ doc( hidden) ]
9+ #[ derive( Debug ) ]
10+ pub enum FlattenFuture < Fut1 , Fut2 > {
11+ First ( Fut1 ) ,
12+ Second ( Fut2 ) ,
13+ Empty ,
14+ }
15+
16+ impl < Fut1 , Fut2 > FlattenFuture < Fut1 , Fut2 > {
17+ pub fn new ( future : Fut1 ) -> FlattenFuture < Fut1 , Fut2 > {
18+ FlattenFuture :: First ( future)
19+ }
20+ }
21+
22+ impl < Fut1 > Future for FlattenFuture < Fut1 , <Fut1 :: Output as IntoFuture >:: Future >
23+ where
24+ Fut1 : Future ,
25+ Fut1 :: Output : IntoFuture ,
26+ {
27+ type Output = <Fut1 :: Output as IntoFuture >:: Output ;
28+
29+ fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
30+ let this = unsafe { self . get_unchecked_mut ( ) } ;
31+ loop {
32+ match this {
33+ FlattenFuture :: First ( fut1) => {
34+ let fut2 = ready ! ( unsafe { Pin :: new_unchecked( fut1) } . poll( cx) ) . into_future ( ) ;
35+ * this = FlattenFuture :: Second ( fut2) ;
36+ }
37+ FlattenFuture :: Second ( fut2) => {
38+ let v = ready ! ( unsafe { Pin :: new_unchecked( fut2) } . poll( cx) ) ;
39+ * this = FlattenFuture :: Empty ;
40+ return Poll :: Ready ( v) ;
41+ }
42+ FlattenFuture :: Empty => unreachable ! ( ) ,
43+ }
44+ }
45+ }
46+ }
You can’t perform that action at this time.
0 commit comments