Skip to content

Instantly share code, notes, and snippets.

@scrogson
Forked from jorendorff/phoenix_ws.rs
Created December 16, 2016 20:26
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 scrogson/c11638947dcda3389b2c4a73958adbde to your computer and use it in GitHub Desktop.
Save scrogson/c11638947dcda3389b2c4a73958adbde to your computer and use it in GitHub Desktop.
// OK so to start with here's the EventHandler trait, just like slack-rs
pub trait EventHandler {
// I don't know what kind of thing EventData should be.
// maybe Json? whatever events actually are in phoenix.
fn on_event(&mut self, channel_name: &str, event_type: &str, event_data: EventData);
fn on_connect(&mut self, ...);
fn on_close(&mut self, ...);
}
fn login_and_run<H: EventHandler>(handler: H, ...) {...}
// Now let's build a user-friendly impl of this trait, "EzClient"
mod ez {
use super::EventHandler;
use super::login_and_run;
// We're going to let users install different callbacks per-channel,
// so make a big HashMap to keep all those callbacks organized.
pub struct EzClient {
channels: HashMap<String, ChannelHandler>
}
impl EzClient {
// let users grab whatever channel they want
fn channel(&mut self, name: &str) -> &mut ChannelHandler {
// if we don't already have a channel with that name, make one
self.channels.entry(name.to_string())
.or_insert_with(ChannelHandler::new)
}
}
impl EventHandler for EzClient {
fn on_event(&mut self, channel_name: &str, event_type: &str, event_data: EventData) {
if let Some(channel) = self.channels.get(channel_name) {
channel.fire(event_type, event_data);
}
}
...
}
// OK, now the channels are where we actually have to worry about storing
// callbacks:
pub struct ChannelHandler {
// The type of a stored callback is `Box<Fn(EventData)>`.
// We have to use a Box because `Fn(EventData)` is unsized.
callbacks: HashMap<String, Box<Fn(EventData)>>
}
impl ChannelHandler {
fn new() -> ChannelHandler { ... }
pub fn on<F>(&mut self, type: &str, callback: F)
where F: Fn(EventData)
{
// Box up this callback and stick it in the hash table! Woohoo!
self.callbacks.insert(type.to_string(), Box::new(callback));
}
fn fire(&self, type: &str, data: EventData) {
// See if there's a callback for this event, and if so, call it!
if let Some(callback) = self.callbacks.get(type) {
callback(data);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment