Skip to content

Instantly share code, notes, and snippets.

@FranklinChen
Forked from anonymous/playground.rs
Last active November 15, 2015 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FranklinChen/c2d519d57fd5a844aec3 to your computer and use it in GitHub Desktop.
Save FranklinChen/c2d519d57fd5a844aec3 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
use std::thread::{spawn, sleep_ms};
use std::sync::mpsc::channel;
fn main() {
// Names of attendees.
let names = vec![format!("A"), format!("B"), format!("C"), format!("D"), format!("E")];
// Create a channel to communicate between attendees and the toaster.
let (toaster_tx, toaster_rx) = channel();
// Iterate over attendees.
for name in names.into_iter() {
// Create a channel to send a bagel down.
let (tx, rx) = channel();
// Clone the toaster channel's transmitter (multiple sender, single receiver)
// so each attendee can send bagels.
let toaster_tx = toaster_tx.clone();
// Spawn a thread for each attendee.
spawn(move || {
// Create an attendee.
let mut a = Attendee::new(name);
// Receive a bagel.
let bagel = rx.recv().unwrap();
// Create a channel to receiver the bagel back from the toaster.
let (ack, rx1) = channel();
// Send the bagel to the toaster along with a way to get it back.
toaster_tx.send((bagel, ack)).unwrap();
// Receive the bagel back from the toaster.
let toasted_bagel = rx1.recv().unwrap();
// Pick up the bagel and eat it.
a.pick_up_bagel(toasted_bagel);
a.eat_breakfast();
});
// Send a bagel to the attendee.
tx.send(Bagel::Raisin).unwrap();
}
// Start the toaster thread.
spawn(move || {
// For each message coming from the toaster...
for (mut bagel, ack) in toaster_rx {
// We get a bagel and one end of a channel.
println!("Toasting {:?}", bagel);
// Toast the bagel.
bagel.toast();
println!("Toasted {:?}", bagel);
// And send it back.
ack.send(bagel).unwrap();
}
});
// Give all the attendees time to toast their bagels.
sleep_ms(1000);
}
struct Attendee {
name: String,
breakfast: Option<Bagel>,
}
#[derive(Debug)]
enum Bagel {
Plain(BagelColour),
Raisin,
}
#[derive(Debug)]
enum BagelColour {
PaleBrown,
DarkBrown,
}
impl Attendee {
fn new(name: String) -> Attendee {
Attendee {
name: name,
breakfast: None,
}
}
fn pick_up_bagel(&mut self, bagel: Bagel) {
self.breakfast = Some(bagel);
}
fn eat_breakfast(&mut self) {
match self.breakfast {
Some(_) => {
self.breakfast = None;
println!("Yum! ({})", self.name);
}
None => println!("I don't have any breakfast :-( ({})", self.name)
}
}
}
impl Bagel {
fn toast(&mut self) {
sleep_ms(10);
match *self {
Bagel::Plain(ref mut c) => {
*c = BagelColour::DarkBrown;
}
_ => {}
}
}
}
@FranklinChen
Copy link
Author

Solution to exercise 2 at http://ncameron.org/oopsla15.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment