3
3
use debug_builders:: DebugStruct ;
4
4
use std:: fmt;
5
5
6
- use { Result , Connection , NotificationsNew } ;
6
+ use { desynchronized , Result , Connection , NotificationsNew } ;
7
7
use message:: BackendMessage :: NotificationResponse ;
8
+ use error:: Error ;
8
9
9
10
/// An asynchronous notification.
10
11
#[ derive( Clone , Debug ) ]
@@ -25,11 +26,49 @@ pub struct Notifications<'conn> {
25
26
impl < ' a > fmt:: Debug for Notifications < ' a > {
26
27
fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
27
28
DebugStruct :: new ( fmt, "Notifications" )
28
- . field ( "pending" , & self . conn . conn . borrow ( ) . notifications . len ( ) )
29
+ . field ( "pending" , & self . len ( ) )
29
30
. finish ( )
30
31
}
31
32
}
32
33
34
+ impl < ' conn > Notifications < ' conn > {
35
+ /// Returns the number of pending notifications.
36
+ pub fn len ( & self ) -> usize {
37
+ self . conn . conn . borrow ( ) . notifications . len ( )
38
+ }
39
+
40
+ /// Returns an iterator over pending notifications.
41
+ ///
42
+ /// # Note
43
+ ///
44
+ /// This iterator may start returning `Some` after previously returning
45
+ /// `None` if more notifications are received.
46
+ pub fn iter < ' a > ( & ' a self ) -> Iter < ' a > {
47
+ Iter {
48
+ conn : self . conn ,
49
+ }
50
+ }
51
+
52
+ /// Returns an iterator over notifications, blocking until one is received
53
+ /// if none are pending.
54
+ ///
55
+ /// The iterator will never return `None`.
56
+ pub fn blocking_iter < ' a > ( & ' a self ) -> BlockingIter < ' a > {
57
+ BlockingIter {
58
+ conn : self . conn ,
59
+ }
60
+ }
61
+ }
62
+
63
+ impl < ' a , ' conn > IntoIterator for & ' a Notifications < ' conn > {
64
+ type Item = Notification ;
65
+ type IntoIter = Iter < ' a > ;
66
+
67
+ fn into_iter ( self ) -> Iter < ' a > {
68
+ self . iter ( )
69
+ }
70
+ }
71
+
33
72
impl < ' conn > NotificationsNew < ' conn > for Notifications < ' conn > {
34
73
fn new ( conn : & ' conn Connection ) -> Notifications < ' conn > {
35
74
Notifications {
@@ -38,41 +77,47 @@ impl<'conn> NotificationsNew<'conn> for Notifications<'conn> {
38
77
}
39
78
}
40
79
41
- impl < ' conn > Iterator for Notifications < ' conn > {
80
+ /// An iterator over pending notifications.
81
+ pub struct Iter < ' a > {
82
+ conn : & ' a Connection ,
83
+ }
84
+
85
+ impl < ' a > Iterator for Iter < ' a > {
42
86
type Item = Notification ;
43
87
44
- /// Returns the oldest pending notification or `None` if there are none.
45
- ///
46
- /// ## Note
47
- ///
48
- /// `next` may return `Some` notification after returning `None` if a new
49
- /// notification was received.
50
88
fn next ( & mut self ) -> Option < Notification > {
51
89
self . conn . conn . borrow_mut ( ) . notifications . pop_front ( )
52
90
}
53
91
}
54
92
55
- impl < ' conn > Notifications < ' conn > {
56
- /// Returns the oldest pending notification.
57
- ///
58
- /// If no notifications are pending, blocks until one arrives.
59
- pub fn next_block ( & mut self ) -> Result < Notification > {
60
- if let Some ( notification) = self . next ( ) {
61
- return Ok ( notification) ;
62
- }
93
+ /// An iterator over notifications which will block if none are pending.
94
+ pub struct BlockingIter < ' a > {
95
+ conn : & ' a Connection ,
96
+ }
63
97
98
+ impl < ' a > Iterator for BlockingIter < ' a > {
99
+ type Item = Result < Notification > ;
100
+
101
+ fn next ( & mut self ) -> Option < Result < Notification > > {
64
102
let mut conn = self . conn . conn . borrow_mut ( ) ;
65
- check_desync ! ( conn) ;
66
- match try!( conn. read_message_with_notification ( ) ) {
67
- NotificationResponse { pid, channel, payload } => {
68
- Ok ( Notification {
103
+ if conn. is_desynchronized ( ) {
104
+ return Some ( Err ( Error :: IoError ( desynchronized ( ) ) ) ) ;
105
+ }
106
+
107
+ if let Some ( notification) = conn. notifications . pop_front ( ) {
108
+ return Some ( Ok ( notification) ) ;
109
+ }
110
+
111
+ match conn. read_message_with_notification ( ) {
112
+ Ok ( NotificationResponse { pid, channel, payload } ) => {
113
+ Some ( Ok ( Notification {
69
114
pid : pid,
70
115
channel : channel,
71
116
payload : payload
72
- } )
117
+ } ) )
73
118
}
119
+ Err ( err) => Some ( Err ( Error :: IoError ( err) ) ) ,
74
120
_ => unreachable ! ( )
75
121
}
76
122
}
77
123
}
78
-
0 commit comments