From 47ebc48140f45f93057ad764e34f1f2223ece5aa Mon Sep 17 00:00:00 2001 From: Raphael Speyer Date: Tue, 21 Apr 2015 02:01:06 +1000 Subject: [PATCH] Implement IntoIterator for Receiver --- src/libstd/sync/mpsc/mod.rs | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 422439fadc1..b3cc133d229 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -306,6 +306,14 @@ pub struct Iter<'a, T: 'a> { rx: &'a Receiver } +/// An owning iterator over messages on a receiver, this iterator will block +/// whenever `next` is called, waiting for a new message, and `None` will be +/// returned when the corresponding channel has hung up. +#[stable(feature = "receiver_into_iter", since = "1.1.0")] +pub struct IntoIter { + rx: Receiver +} + /// The sending-half of Rust's asynchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. #[stable(feature = "rust1", since = "1.0.0")] @@ -899,6 +907,29 @@ impl<'a, T> Iterator for Iter<'a, T> { fn next(&mut self) -> Option { self.rx.recv().ok() } } +#[stable(feature = "receiver_into_iter", since = "1.1.0")] +impl<'a, T> IntoIterator for &'a Receiver { + type Item = T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { self.iter() } +} + +impl Iterator for IntoIter { + type Item = T; + fn next(&mut self) -> Option { self.rx.recv().ok() } +} + +#[stable(feature = "receiver_into_iter", since = "1.1.0")] +impl IntoIterator for Receiver { + type Item = T; + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + IntoIter { rx: self } + } +} + #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] impl Drop for Receiver { @@ -1507,6 +1538,32 @@ fn test_recv_iter_break() { assert_eq!(count_rx.recv().unwrap(), 4); } + #[test] + fn test_recv_into_iter_owned() { + let mut iter = { + let (tx, rx) = channel::(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + + rx.into_iter() + }; + assert_eq!(iter.next().unwrap(), 1); + assert_eq!(iter.next().unwrap(), 2); + assert_eq!(iter.next().is_none(), true); + } + + #[test] + fn test_recv_into_iter_borrowed() { + let (tx, rx) = channel::(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + drop(tx); + let mut iter = (&rx).into_iter(); + assert_eq!(iter.next().unwrap(), 1); + assert_eq!(iter.next().unwrap(), 2); + assert_eq!(iter.next().is_none(), true); + } + #[test] fn try_recv_states() { let (tx1, rx1) = channel::();