Last active
February 15, 2017 03:23
-
-
Save khadiwala/8e0314484f454e868ab3fa5564c4fb7a to your computer and use it in GitHub Desktop.
chat.rs with unfold
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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