use std::collections::HashMap; use std::sync::LazyLock; use tokio::sync::RwLock; pub(crate) struct MessageDispatcher where H: Fn(String) + Send + Sync, { handlers: RwLock>, } pub(crate) static DISPATCHER: LazyLock>> = LazyLock::new(MessageDispatcher::new); impl MessageDispatcher where H: Fn(String) + Send + Sync, { fn new() -> Self { Self { handlers: RwLock::new(HashMap::new()), } } pub(crate) async fn register_handler(&self, handler_name: String, handler: H) { let mut handlers = self.handlers.write().await; handlers.insert(handler_name, handler); } pub(crate) async fn dispatch(&self, handler_name: String, message: String) { let handlers = self.handlers.read().await; match handlers.get(&handler_name) { Some(handler) => handler(message), None => log::error!( "The handler corresponds to this kind of message hasn't been registered!" ), } } } mod test { #[tokio::test] async fn test_dispatch() { use super::DISPATCHER; DISPATCHER .register_handler( "UserLogin".into(), Box::new(|message| println!("Received message: {message}")), ) .await; DISPATCHER .register_handler( "UserSignUp".into(), Box::new(|message| println!("Received message: {message}")), ) .await; DISPATCHER .dispatch("UserLogin".into(), "I want to login".into()) .await; DISPATCHER .dispatch("UserSignUp".into(), "I want to signup".into()) .await; } }