Skip to content

Instantly share code, notes, and snippets.

@khadiwala
Last active February 15, 2017 03:23
Show Gist options
  • Save khadiwala/8e0314484f454e868ab3fa5564c4fb7a to your computer and use it in GitHub Desktop.
Save khadiwala/8e0314484f454e868ab3fa5564c4fb7a to your computer and use it in GitHub Desktop.
chat.rs with unfold
// from chat.rs
// Model the read portion of this socket by mapping an infinite
// iterator to each line off the socket. This "loop" is then
// terminated with an error once we hit EOF on the socket.
let iter = stream::iter(iter::repeat(()).map(Ok::<(), Error>));
let socket_reader = iter.fold(reader, move |reader, _| {
// Read a line off the socket, failing if we're at EOF
let line = io::read_until(reader, b'\n', Vec::new());
let line = line.and_then(|(reader, vec)| {
if vec.len() == 0 {
Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
} else {
Ok((reader, vec))
}
});
// Convert the bytes we read into a string, and then send that
// string to all other connected clients.
let line = line.map(|(reader, vec)| {
(reader, String::from_utf8(vec))
});
let connections = connections_inner.clone();
line.map(move |(reader, message)| {
println!("{}: {:?}", addr, message);
let mut conns = connections.borrow_mut();
if let Ok(msg) = message {
// For each open connection except the sender, send the
// string via the channel.
let iter = conns.iter_mut()
.filter(|&(&k, _)| k != addr)
.map(|(_, v)| v);
for tx in iter {
tx.send(format!("{}: {}", addr, msg)).unwrap();
}
} else {
let tx = conns.get_mut(&addr).unwrap();
tx.send("You didn't send valid UTF-8.".to_string()).unwrap();
}
reader
})
});
// using unfold instead
let socket_reader = unfold(reader, move |reader| {
// Read a line off the socket, failing if we're at EOF
Some(io::read_until(reader, b'\n', Vec::new())
.and_then(|(reader, vec)| if vec.len() == 0 {
Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
} else {
Ok((vec, reader))
}))
})
.map(String::from_utf8)
.for_each(move |message| {
println!("{}: {:?}", addr, message);
let mut conns = connections_inner.borrow_mut();
if let Ok(msg) = message {
// For each open connection except the sender, send the
// string via the channel.
let iter = conns.iter_mut()
.filter(|&(&k, _)| k != addr)
.map(|(_, v)| v);
for tx in iter {
tx.send(format!("{}: {}", addr, msg)).unwrap();
}
} else {
let tx = conns.get_mut(&addr).unwrap();
tx.send("You didn't send valid UTF-8.".to_string()).unwrap();
}
Ok(())
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment