emitix 1.1.3

Emitix - A Rust library for event-driven programming
Documentation
use uuid::Uuid;
use leptos::callback::Callback;
use std::{
    collections::HashMap,
    sync::{Arc, RwLock},
};

pub(super) type ListenerMap<T> = HashMap<String, HashMap<Uuid, Callback<T>>>;

pub(super) struct ListenerRegistry<T: Clone + Send + Sync + 'static> {
    listeners: ListenerMap<T>,
    links:     HashMap<Uuid, String>,
}

impl<T: Clone + Send + Sync + 'static> ListenerRegistry<T> {
    pub(super) fn new() -> Self {
        Self {
            listeners: HashMap::new(),
            links:     HashMap::new(),
        }
    }

    pub(super) fn clear(&mut self) {
        self.listeners.clear();
        self.links.clear();
    }

    pub(super) fn listeners(&self) -> &ListenerMap<T> {
        &self.listeners
    }

    pub(super) fn remove_listener(&mut self, listener_id: Uuid) -> bool {
        if let Some(event_kind) = self.links.remove(&listener_id) {
            if let Some(listeners) = self.listeners.get_mut(&event_kind) {
                listeners.remove(&listener_id);
                if listeners.is_empty() {
                    self.listeners.remove(&event_kind);
                }

                return true;
            }
        }

        false
    }

    pub(super) fn remove_listeners_by_kind(&mut self, event_kind: &str) -> usize {
        match self.listeners.remove(event_kind) {
            None => 0,
            Some(listeners) => {
                let sz = listeners.len();
                for listener_id in listeners.keys() {
                    self.links.remove(listener_id);
                }

                sz
            }
        }
    }

    pub(super) fn register_listener<F>(&mut self, event_kind: &str, listener: F) -> Uuid
    where
        F: FnMut(T) + Send + Sync + 'static, {
        let f = Arc::new(RwLock::new(listener));
        let receiver = Callback::new(move |arg| {
            let f = Arc::clone(&f);
            if let Ok(mut caller) = f.write() {
                caller(arg);
            }
        });

        let listener_id = Uuid::new_v4();
        let event_kind = event_kind.to_string();
        let entry = self.listeners.entry(event_kind.clone()).or_default();

        entry.insert(listener_id, receiver);
        self.links.insert(listener_id, event_kind);

        listener_id
    }
}