@@ -144,6 +144,33 @@ pub fn repeat<T>(item: T) -> impl Stream<Item = T>
144
144
} )
145
145
}
146
146
147
+ pub fn flatten < St , SubSt , T > ( stream : St ) -> impl Stream < Item = T >
148
+ where SubSt : Stream < Item = T > ,
149
+ St : Stream < Item = SubSt > ,
150
+ {
151
+ let stream = Box :: pin ( stream) ;
152
+ futures:: stream:: unfold ( ( Some ( stream) , None ) , async move | ( mut state_stream, mut state_substream) | {
153
+ loop {
154
+ if let Some ( mut substream) = state_substream. take ( ) {
155
+ if let Some ( item) = await ! ( next( & mut substream) ) {
156
+ return Some ( ( item, ( state_stream, Some ( substream) ) ) )
157
+ } else {
158
+ continue ;
159
+ }
160
+ }
161
+ if let Some ( mut stream) = state_stream. take ( ) {
162
+ if let Some ( substream) = await ! ( next( & mut stream) ) {
163
+ let substream = Box :: pin ( substream) ;
164
+ state_stream = Some ( stream) ;
165
+ state_substream = Some ( substream) ;
166
+ continue ;
167
+ }
168
+ }
169
+ return None ;
170
+ }
171
+ } )
172
+ }
173
+
147
174
#[ cfg( test) ]
148
175
mod tests {
149
176
use futures:: executor;
@@ -256,4 +283,16 @@ mod tests {
256
283
257
284
assert_eq ! ( vec![ 9 , 9 , 9 ] , executor:: block_on( collect:: <_, Vec <_>>( stream) ) ) ;
258
285
}
286
+
287
+ #[ test]
288
+ fn test_flatten ( ) {
289
+ let stream0 = iter ( 0 ..0 ) ;
290
+ let stream1 = iter ( 1 ..4 ) ;
291
+ let stream2 = iter ( 4 ..7 ) ;
292
+ let stream3 = iter ( 7 ..10 ) ;
293
+ let stream = iter ( vec ! [ stream0, stream1, stream2, stream3] ) ;
294
+ let stream = flatten ( stream) ;
295
+
296
+ assert_eq ! ( vec![ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] , executor:: block_on( collect:: <_, Vec <_>>( stream) ) ) ;
297
+ }
259
298
}
0 commit comments