Skip to content

Commit

Permalink
Add an iterator for receiving messages from GenericPorts
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanzab committed Nov 27, 2013
1 parent 18687a9 commit 31da6b7
Showing 1 changed file with 84 additions and 3 deletions.
87 changes: 84 additions & 3 deletions src/libstd/comm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Message passing
#[allow(missing_doc)];

use clone::Clone;
use iter::Iterator;
use kinds::Send;
use option::Option;
use rtcomm = rt::comm;
Expand Down Expand Up @@ -43,10 +44,35 @@ pub trait GenericPort<T> {
/// Receives a message, or fails if the connection closes.
fn recv(&self) -> T;

/** Receives a message, or returns `none` if
the connection is closed or closes.
*/
/// Receives a message, or returns `none` if
/// the connection is closed or closes.
fn try_recv(&self) -> Option<T>;

/// Returns an iterator that breaks once the connection closes.
///
/// # Example
///
/// ~~~rust
/// do spawn {
/// for x in port.recv_iter() {
/// if pred(x) { break; }
/// println!("{}", x);
/// }
/// }
/// ~~~
fn recv_iter<'a>(&'a self) -> RecvIterator<'a, Self> {
RecvIterator { port: self }
}
}

pub struct RecvIterator<'a, P> {
priv port: &'a P,
}

impl<'a, T, P: GenericPort<T>> Iterator<T> for RecvIterator<'a, P> {
fn next(&mut self) -> Option<T> {
self.port.try_recv()
}
}

/// Ports that can `peek`
Expand Down Expand Up @@ -227,3 +253,58 @@ impl<T: Send> Clone for SharedPort<T> {
SharedPort { x: p.clone() }
}
}

#[cfg(test)]
mod tests {
use comm::*;
use prelude::*;

#[test]
fn test_nested_recv_iter() {
let (port, chan) = stream::<int>();
let (total_port, total_chan) = oneshot::<int>();

do spawn {
let mut acc = 0;
for x in port.recv_iter() {
acc += x;
for x in port.recv_iter() {
acc += x;
for x in port.try_recv().move_iter() {
acc += x;
total_chan.send(acc);
}
}
}
}

chan.send(3);
chan.send(1);
chan.send(2);
assert_eq!(total_port.recv(), 6);
}

#[test]
fn test_recv_iter_break() {
let (port, chan) = stream::<int>();
let (count_port, count_chan) = oneshot::<int>();

do spawn {
let mut count = 0;
for x in port.recv_iter() {
if count >= 3 {
count_chan.send(count);
break;
} else {
count += x;
}
}
}

chan.send(2);
chan.send(2);
chan.send(2);
chan.send(2);
assert_eq!(count_port.recv(), 4);
}
}

0 comments on commit 31da6b7

Please sign in to comment.