diff --git a/futures-channel/src/mpsc/mod.rs b/futures-channel/src/mpsc/mod.rs index edbac7aa3..61763abe1 100644 --- a/futures-channel/src/mpsc/mod.rs +++ b/futures-channel/src/mpsc/mod.rs @@ -836,6 +836,20 @@ impl UnboundedSender { let ptr = self.0.as_ref().map(|inner| inner.ptr()); ptr.hash(hasher); } + + /// Return the number of messages in the queue or 0 if channel is disconnected. + pub fn len(&self) -> usize { + if let Some(sender) = &self.0 { + decode_state(sender.inner.state.load(SeqCst)).num_messages + } else { + 0 + } + } + + /// Return false is channel has no queued messages, true otherwise. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } } impl Clone for Sender { diff --git a/futures-channel/tests/mpsc.rs b/futures-channel/tests/mpsc.rs index f18fc3d66..3d8290865 100644 --- a/futures-channel/tests/mpsc.rs +++ b/futures-channel/tests/mpsc.rs @@ -630,3 +630,26 @@ fn send_backpressure_multi_senders() { let item = block_on(rx.next()).unwrap(); assert_eq!(item, 2); } + +/// Test that empty channel has zero length and that non-empty channel has length equal to number +/// of enqueued items +#[test] +fn unbounded_len() { + let (tx, mut rx) = mpsc::unbounded(); + assert_eq!(tx.len(), 0); + assert!(tx.is_empty()); + tx.unbounded_send(1).unwrap(); + assert_eq!(tx.len(), 1); + assert!(!tx.is_empty()); + tx.unbounded_send(2).unwrap(); + assert_eq!(tx.len(), 2); + assert!(!tx.is_empty()); + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 1); + assert_eq!(tx.len(), 1); + assert!(!tx.is_empty()); + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 2); + assert_eq!(tx.len(), 0); + assert!(tx.is_empty()); +}