@@ -10,47 +10,58 @@ use crate::task::{Context, Poll};
10
10
/// A stream that only yields one element once every `duration`, and drops all others.
11
11
/// #[doc(hidden)]
12
12
#[ allow( missing_debug_implementations) ]
13
- pub struct Throttle < S > {
13
+ pub struct Throttle < S , T > {
14
14
stream : S ,
15
15
duration : Duration ,
16
16
delay : Option < Delay > ,
17
+ last : Option < T > ,
17
18
}
18
19
19
- impl < S : Unpin > Unpin for Throttle < S > { }
20
+ impl < S : Unpin , T > Unpin for Throttle < S , T > { }
20
21
21
- impl < S : Stream > Throttle < S > {
22
+ impl < S : Stream > Throttle < S , S :: Item > {
22
23
pin_utils:: unsafe_pinned!( stream: S ) ;
23
24
pin_utils:: unsafe_unpinned!( duration: Duration ) ;
24
25
pin_utils:: unsafe_pinned!( delay: Option <Delay >) ;
26
+ pin_utils:: unsafe_unpinned!( last: Option <S :: Item >) ;
25
27
26
28
pub ( super ) fn new ( stream : S , duration : Duration ) -> Self {
27
29
Throttle {
28
30
stream,
29
31
duration,
30
32
delay : None ,
33
+ last : None ,
31
34
}
32
35
}
33
36
}
34
37
35
- impl < S : Stream > Stream for Throttle < S > {
38
+ impl < S : Stream > Stream for Throttle < S , S :: Item > {
36
39
type Item = S :: Item ;
37
40
38
41
fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < S :: Item > > {
39
- match self . as_mut ( ) . stream ( ) . poll_next ( cx) {
40
- Poll :: Ready ( v) => match self . as_mut ( ) . delay ( ) . as_pin_mut ( ) {
41
- None => {
42
+ if let Some ( d) = self . as_mut ( ) . delay ( ) . as_pin_mut ( ) {
43
+ if d. poll ( cx) . is_ready ( ) {
44
+ if let Some ( v) = self . as_mut ( ) . last ( ) . take ( ) {
45
+ // Sets last to None.
42
46
* self . as_mut ( ) . delay ( ) = Some ( Delay :: new ( self . duration ) ) ;
43
- Poll :: Ready ( v )
47
+ return Poll :: Ready ( Some ( v ) ) ;
44
48
}
45
- Some ( d) => match d. poll ( cx) {
46
- Poll :: Ready ( _) => {
47
- * self . as_mut ( ) . delay ( ) = Some ( Delay :: new ( self . duration ) ) ;
48
- Poll :: Ready ( v)
49
- }
50
- Poll :: Pending => Poll :: Pending ,
51
- } ,
52
- } ,
49
+ }
50
+ }
51
+
52
+ match self . as_mut ( ) . stream ( ) . poll_next ( cx) {
53
53
Poll :: Pending => Poll :: Pending ,
54
+ Poll :: Ready ( None ) => return Poll :: Ready ( None ) ,
55
+ Poll :: Ready ( Some ( v) ) => {
56
+ if self . as_mut ( ) . delay ( ) . is_some ( ) {
57
+ * self . as_mut ( ) . last ( ) = Some ( v) ;
58
+ cx. waker ( ) . wake_by_ref ( ) ; // Continue driving even though emitting Pending
59
+ return Poll :: Pending ;
60
+ }
61
+
62
+ * self . as_mut ( ) . delay ( ) = Some ( Delay :: new ( self . duration ) ) ;
63
+ Poll :: Ready ( Some ( v) )
64
+ }
54
65
}
55
66
}
56
67
}
0 commit comments