@@ -54,6 +54,24 @@ pub fn filter<St, Fut, F>(stream: St, f: F) -> impl Stream<Item = St::Item>
54
54
} )
55
55
}
56
56
57
+ pub fn filter_map < St , Fut , F , U > ( stream : St , f : F ) -> impl Stream < Item = U >
58
+ where St : Stream ,
59
+ F : FnMut ( St :: Item ) -> Fut ,
60
+ Fut : Future < Output = Option < U > >
61
+ {
62
+ let stream = Box :: pin ( stream) ;
63
+ futures:: stream:: unfold ( ( stream, f) , async move | ( mut stream, mut f) | {
64
+ while let Some ( item) = await ! ( next( & mut stream) ) {
65
+ if let Some ( item) = await ! ( f( item) ) {
66
+ return Some ( ( item, ( stream, f) ) )
67
+ } else {
68
+ continue ;
69
+ }
70
+ } ;
71
+ None
72
+ } )
73
+ }
74
+
57
75
#[ cfg( test) ]
58
76
mod tests {
59
77
use futures:: { executor, future, stream} ;
@@ -93,4 +111,14 @@ mod tests {
93
111
assert_eq ! ( vec![ 2 , 4 , 6 , 8 , 10 ] , executor:: block_on( collect:: <_, Vec <_>>( evens) ) ) ;
94
112
}
95
113
114
+ #[ test]
115
+ fn test_filter_map ( ) {
116
+ let stream = stream:: iter ( 1 ..=10 ) ;
117
+ let evens = filter_map ( stream, |x| {
118
+ let ret = if x % 2 == 0 { Some ( x + 1 ) } else { None } ;
119
+ future:: ready ( ret)
120
+ } ) ;
121
+
122
+ assert_eq ! ( vec![ 3 , 5 , 7 , 9 , 11 ] , executor:: block_on( collect:: <_, Vec <_>>( evens) ) ) ;
123
+ }
96
124
}
0 commit comments