1
1
use futures:: stream:: Stream ;
2
+ use futures:: future:: Future ;
2
3
use core:: pin:: Pin ;
3
4
use pin_utils:: pin_mut;
4
5
@@ -24,8 +25,8 @@ pub async fn collect<St, C>(stream: St) -> C
24
25
}
25
26
26
27
pub fn map < St , U , F > ( stream : St , f : F ) -> impl Stream < Item = U >
27
- where F : FnMut ( St :: Item ) -> U ,
28
- St : Stream ,
28
+ where St : Stream ,
29
+ F : FnMut ( St :: Item ) -> U ,
29
30
{
30
31
let stream = Box :: pin ( stream) ;
31
32
futures:: stream:: unfold ( ( stream, f) , async move | ( mut stream, mut f) | {
@@ -34,9 +35,28 @@ pub fn map<St, U, F>(stream: St, f: F) -> impl Stream<Item = U>
34
35
} )
35
36
}
36
37
38
+ pub fn filter < St , Fut , F > ( stream : St , f : F ) -> impl Stream < Item = St :: Item >
39
+ where St : Stream ,
40
+ F : FnMut ( & St :: Item ) -> Fut ,
41
+ Fut : Future < Output = bool >
42
+ {
43
+ let stream = Box :: pin ( stream) ;
44
+ futures:: stream:: unfold ( ( stream, f) , async move | ( mut stream, mut f) | {
45
+ while let Some ( item) = await ! ( next( & mut stream) ) {
46
+ let matched = await ! ( f( & item) ) ;
47
+ if matched {
48
+ return Some ( ( item, ( stream, f) ) )
49
+ } else {
50
+ continue ;
51
+ }
52
+ } ;
53
+ None
54
+ } )
55
+ }
56
+
37
57
#[ cfg( test) ]
38
58
mod tests {
39
- use futures:: { stream , executor } ;
59
+ use futures:: { executor , future , stream } ;
40
60
use crate :: stream:: * ;
41
61
42
62
#[ test]
@@ -64,4 +84,13 @@ mod tests {
64
84
65
85
assert_eq ! ( vec![ 2 , 4 , 6 ] , executor:: block_on( collect:: <_, Vec <_>>( stream) ) ) ;
66
86
}
87
+
88
+ #[ test]
89
+ fn test_filter ( ) {
90
+ let stream = stream:: iter ( 1 ..=10 ) ;
91
+ let evens = filter ( stream, |x| future:: ready ( x % 2 == 0 ) ) ;
92
+
93
+ assert_eq ! ( vec![ 2 , 4 , 6 , 8 , 10 ] , executor:: block_on( collect:: <_, Vec <_>>( evens) ) ) ;
94
+ }
95
+
67
96
}
0 commit comments