78
78
// happens-before semantics required for the acquire / release semantics used
79
79
// by the queue structure.
80
80
81
+ use core:: future:: Future ;
81
82
use futures_core:: stream:: { FusedStream , Stream } ;
82
83
use futures_core:: task:: __internal:: AtomicWaker ;
83
84
use futures_core:: task:: { Context , Poll , Waker } ;
85
+ use futures_core:: FusedFuture ;
84
86
use std:: fmt;
85
87
use std:: pin:: Pin ;
86
88
use std:: sync:: atomic:: AtomicUsize ;
@@ -167,7 +169,7 @@ enum SendErrorKind {
167
169
Disconnected ,
168
170
}
169
171
170
- /// The error type returned from [`try_recv`](Receiver ::try_recv) .
172
+ /// Error returned by [`Receiver:: try_recv`] or [`UnboundedReceiver ::try_recv`] .
171
173
#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
172
174
pub enum TryRecvError {
173
175
/// The channel is empty but not closed.
@@ -177,6 +179,18 @@ pub enum TryRecvError {
177
179
Closed ,
178
180
}
179
181
182
+ /// Error returned by the future returned by [`Receiver::recv()`] or [`UnboundedReceiver::recv()`].
183
+ /// Received when the channel is empty and closed.
184
+ #[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
185
+ pub struct RecvError ;
186
+
187
+ /// Future returned by [`Receiver::recv()`] or [`UnboundedReceiver::recv()`].
188
+ #[ derive( Debug ) ]
189
+ #[ must_use = "futures do nothing unless you `.await` or poll them" ]
190
+ pub struct Recv < ' a , St : ?Sized > {
191
+ stream : & ' a mut St ,
192
+ }
193
+
180
194
impl fmt:: Display for SendError {
181
195
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
182
196
if self . is_full ( ) {
@@ -189,6 +203,14 @@ impl fmt::Display for SendError {
189
203
190
204
impl std:: error:: Error for SendError { }
191
205
206
+ impl fmt:: Display for RecvError {
207
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
208
+ write ! ( f, "receive failed because channel is empty and closed" )
209
+ }
210
+ }
211
+
212
+ impl std:: error:: Error for RecvError { }
213
+
192
214
impl SendError {
193
215
/// Returns `true` if this error is a result of the channel being full.
194
216
pub fn is_full ( & self ) -> bool {
@@ -979,6 +1001,12 @@ impl<T> fmt::Debug for UnboundedSender<T> {
979
1001
*/
980
1002
981
1003
impl < T > Receiver < T > {
1004
+ /// Waits for a message from the channel.
1005
+ /// If the channel is empty and closed, returns [`RecvError`].
1006
+ pub fn recv ( & mut self ) -> Recv < ' _ , Self > {
1007
+ Recv :: new ( self )
1008
+ }
1009
+
982
1010
/// Closes the receiving half of a channel, without dropping it.
983
1011
///
984
1012
/// This prevents any further messages from being sent on the channel while
@@ -1121,6 +1149,31 @@ impl<T> Stream for Receiver<T> {
1121
1149
}
1122
1150
}
1123
1151
1152
+ impl < St : ?Sized + Unpin > Unpin for Recv < ' _ , St > { }
1153
+ impl < ' a , St : ?Sized + Stream + Unpin > Recv < ' a , St > {
1154
+ fn new ( stream : & ' a mut St ) -> Self {
1155
+ Self { stream }
1156
+ }
1157
+ }
1158
+
1159
+ impl < St : ?Sized + FusedStream + Unpin > FusedFuture for Recv < ' _ , St > {
1160
+ fn is_terminated ( & self ) -> bool {
1161
+ self . stream . is_terminated ( )
1162
+ }
1163
+ }
1164
+
1165
+ impl < St : ?Sized + Stream + Unpin > Future for Recv < ' _ , St > {
1166
+ type Output = Result < St :: Item , RecvError > ;
1167
+
1168
+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
1169
+ match Pin :: new ( & mut self . stream ) . poll_next ( cx) {
1170
+ Poll :: Ready ( Some ( msg) ) => Poll :: Ready ( Ok ( msg) ) ,
1171
+ Poll :: Ready ( None ) => Poll :: Ready ( Err ( RecvError ) ) ,
1172
+ Poll :: Pending => Poll :: Pending ,
1173
+ }
1174
+ }
1175
+ }
1176
+
1124
1177
impl < T > Drop for Receiver < T > {
1125
1178
fn drop ( & mut self ) {
1126
1179
// Drain the channel of all pending messages
@@ -1164,6 +1217,12 @@ impl<T> fmt::Debug for Receiver<T> {
1164
1217
}
1165
1218
1166
1219
impl < T > UnboundedReceiver < T > {
1220
+ /// Waits for a message from the channel.
1221
+ /// If the channel is empty and closed, returns [`RecvError`].
1222
+ pub fn recv ( & mut self ) -> Recv < ' _ , Self > {
1223
+ Recv :: new ( self )
1224
+ }
1225
+
1167
1226
/// Closes the receiving half of a channel, without dropping it.
1168
1227
///
1169
1228
/// This prevents any further messages from being sent on the channel while
0 commit comments