sse-client 1.1.1

Client for streams of Server-Sent Events
Documentation
use std::collections::HashMap;

pub struct Bus<ListenerData> where ListenerData: Clone {
    listeners: HashMap<String, Vec<Box<dyn Fn(ListenerData) + Send>>>
}

impl<ListenerData> Bus <ListenerData> where ListenerData: Clone {
    pub fn new() -> Bus<ListenerData> {
        let listeners = HashMap::new();
        Bus { listeners }
    }

    pub fn subscribe<F>(&mut self, name: String, listener: F) where F: Fn(ListenerData) + Send + 'static {
        let listener = Box::new(listener);
        if self.listeners.contains_key(&name) {
            self.listeners.get_mut(&name).unwrap().push(listener);
        } else {
            self.listeners.insert(name, vec!(listener));
        }
    }

    pub fn publish(&self, name: String, data: ListenerData) {
        if self.listeners.contains_key(&name) {
            for listener in self.listeners.get(&name).unwrap().iter() {
                listener(data.clone())
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::mpsc;

    #[test]
    fn should_trigger_listener() {
        let (tx, rx) = mpsc::channel();
        let mut bus: Bus<String> = Bus::new();
        bus.subscribe("event".to_string(), move |data| {
            tx.send(data).unwrap();
        });

        bus.publish("event".to_string(), "data".to_string());

        let message = rx.recv().unwrap();
        assert_eq!(message, "data");
    }

    #[test]
    fn should_allow_multiple_listener_for_same_event() {
        let (tx, rx) = mpsc::channel();
        let tx2 = tx.clone();
        let mut bus = Bus::new();

        bus.subscribe("event".to_string(), move |data| {
            tx.send(data).unwrap();
        });

        bus.subscribe("event".to_string(), move |data| {
            tx2.send(data).unwrap();
        });

        bus.publish("event".to_string(), "data".to_string());

        let message = rx.recv().unwrap();
        let message2 = rx.recv().unwrap();
        assert_eq!(message, "data");
        assert_eq!(message2, "data");
    }

    #[test]
    fn should_trigger_only_listener_for_published_event() {
        let (tx, rx) = mpsc::channel();
        let tx2 = tx.clone();
        let mut bus = Bus::new();

        bus.subscribe("event".to_string(), move |data| {
            tx.send(data).unwrap();
        });

        bus.subscribe("another event".to_string(), move |data| {
            tx2.send(data).unwrap();
        });

        bus.publish("event".to_string(), "data".to_string());

        let message = rx.recv().unwrap();
        assert_eq!(message, "data");
        assert!(rx.try_recv().is_err());
    }

    #[test]
    fn should_work_with_other_types() {
        let (tx, rx) = mpsc::channel();
        let mut bus: Bus<i32> = Bus::new();
        bus.subscribe("event".to_string(), move |data| {
            tx.send(data).unwrap();
        });

        bus.publish("event".to_string(), 3);

        let message = rx.recv().unwrap();
        assert_eq!(message, 3);
    }

    #[test]
    fn should_not_break_when_published_event_with_no_subscribers() {
        let bus: Bus<String> = Bus::new();
        bus.publish("event".to_string(), "data".to_string());
    }
}