1
1
use super :: assert_stream;
2
- use crate :: stream:: { select_with_strategy, ExitStrategy , PollNext , SelectWithStrategy } ;
2
+ use crate :: stream:: {
3
+ select_with_strategy, ClosedStreams , ExitStrategy , PollNext , SelectWithStrategy ,
4
+ } ;
3
5
use core:: pin:: Pin ;
4
6
use futures_core:: stream:: { FusedStream , Stream } ;
5
7
use futures_core:: task:: { Context , Poll } ;
@@ -9,12 +11,42 @@ pin_project! {
9
11
/// Stream for the [`select()`] function.
10
12
#[ derive( Debug ) ]
11
13
#[ must_use = "streams do nothing unless polled" ]
12
- pub struct Select <St1 , St2 > {
14
+ pub struct Select <St1 , St2 , Exit > {
13
15
#[ pin]
14
- inner: SelectWithStrategy <St1 , St2 , fn ( & mut PollNext ) -> PollNext , PollNext >,
16
+ inner: SelectWithStrategy <St1 , St2 , fn ( & mut PollNext ) -> PollNext , PollNext , Exit >,
15
17
}
16
18
}
17
19
20
+ #[ derive( Debug ) ]
21
+ pub struct ExitWhenBothFinished { }
22
+
23
+ impl ExitStrategy for ExitWhenBothFinished {
24
+ #[ inline]
25
+ fn is_terminated ( closed_streams : ClosedStreams ) -> bool {
26
+ match closed_streams {
27
+ ClosedStreams :: Both => true ,
28
+ _ => false ,
29
+ }
30
+ }
31
+ }
32
+
33
+ #[ derive( Debug ) ]
34
+ pub struct ExitWhenEitherFinished { }
35
+
36
+ impl ExitStrategy for ExitWhenEitherFinished {
37
+ #[ inline]
38
+ fn is_terminated ( closed_streams : ClosedStreams ) -> bool {
39
+ match closed_streams {
40
+ ClosedStreams :: None => false ,
41
+ _ => true ,
42
+ }
43
+ }
44
+ }
45
+
46
+ fn round_robin ( last : & mut PollNext ) -> PollNext {
47
+ last. toggle ( )
48
+ }
49
+
18
50
/// This function will attempt to pull items from both streams. Each
19
51
/// stream will be polled in a round-robin fashion, and whenever a stream is
20
52
/// ready to yield an item that item is yielded.
@@ -44,42 +76,31 @@ pin_project! {
44
76
/// }
45
77
/// # });
46
78
/// ```
47
- pub fn select < St1 , St2 > ( stream1 : St1 , stream2 : St2 ) -> Select < St1 , St2 >
79
+ pub fn select < St1 , St2 > ( stream1 : St1 , stream2 : St2 ) -> Select < St1 , St2 , ExitWhenBothFinished >
48
80
where
49
81
St1 : Stream ,
50
82
St2 : Stream < Item = St1 :: Item > ,
51
83
{
52
- select_with_exit ( stream1, stream2, ExitStrategy :: WhenBothFinish )
84
+ assert_stream :: < St1 :: Item , _ > ( Select {
85
+ inner : select_with_strategy ( stream1, stream2, round_robin) ,
86
+ } )
53
87
}
54
88
55
89
/// Same as `select`, but finishes when either stream finishes
56
- pub fn select_early_exit < St1 , St2 > ( stream1 : St1 , stream2 : St2 ) -> Select < St1 , St2 >
57
- where
58
- St1 : Stream ,
59
- St2 : Stream < Item = St1 :: Item > ,
60
- {
61
- select_with_exit ( stream1, stream2, ExitStrategy :: WhenEitherFinish )
62
- }
63
-
64
- fn select_with_exit < St1 , St2 > (
90
+ pub fn select_early_exit < St1 , St2 > (
65
91
stream1 : St1 ,
66
92
stream2 : St2 ,
67
- exit_strategy : ExitStrategy ,
68
- ) -> Select < St1 , St2 >
93
+ ) -> Select < St1 , St2 , ExitWhenEitherFinished >
69
94
where
70
95
St1 : Stream ,
71
96
St2 : Stream < Item = St1 :: Item > ,
72
97
{
73
- fn round_robin ( last : & mut PollNext ) -> PollNext {
74
- last. toggle ( )
75
- }
76
-
77
98
assert_stream :: < St1 :: Item , _ > ( Select {
78
- inner : select_with_strategy ( stream1, stream2, round_robin, exit_strategy ) ,
99
+ inner : select_with_strategy ( stream1, stream2, round_robin) ,
79
100
} )
80
101
}
81
102
82
- impl < St1 , St2 > Select < St1 , St2 > {
103
+ impl < St1 , St2 , Exit > Select < St1 , St2 , Exit > {
83
104
/// Acquires a reference to the underlying streams that this combinator is
84
105
/// pulling from.
85
106
pub fn get_ref ( & self ) -> ( & St1 , & St2 ) {
@@ -114,20 +135,22 @@ impl<St1, St2> Select<St1, St2> {
114
135
}
115
136
}
116
137
117
- impl < St1 , St2 > FusedStream for Select < St1 , St2 >
138
+ impl < St1 , St2 , Exit > FusedStream for Select < St1 , St2 , Exit >
118
139
where
119
140
St1 : Stream ,
120
141
St2 : Stream < Item = St1 :: Item > ,
142
+ Exit : ExitStrategy ,
121
143
{
122
144
fn is_terminated ( & self ) -> bool {
123
145
self . inner . is_terminated ( )
124
146
}
125
147
}
126
148
127
- impl < St1 , St2 > Stream for Select < St1 , St2 >
149
+ impl < St1 , St2 , Exit > Stream for Select < St1 , St2 , Exit >
128
150
where
129
151
St1 : Stream ,
130
152
St2 : Stream < Item = St1 :: Item > ,
153
+ Exit : ExitStrategy ,
131
154
{
132
155
type Item = St1 :: Item ;
133
156
0 commit comments