-
-
Save scrogson/c11638947dcda3389b2c4a73958adbde to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// 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