lps 0.1.0

A local publish-subscribe pattern implementation
Documentation
use crate::{channel::*, *};

use std::collections::HashMap;
use std::sync::{Arc, Mutex};

pub struct MessageTopic {
    msg_type_id: MessageTypeId,
    msg_senders: Mutex<HashMap<MessageChannelId, MessageSender>>,
}

impl MessageTopic {
    pub fn new(msg_type_id: MessageTypeId) -> Self {
        Self {
            msg_type_id,
            msg_senders: Mutex::new(HashMap::new()),
        }
    }

    pub fn new_typed<M: Message>() -> Self {
        Self::new(MessageTypeId::of::<M>())
    }

    pub(crate) fn create_message_channel(&self) -> MessageReceiver {
        let (msg_send, msg_recv) = message_channel_new(self.msg_type_id);
        let mut msg_senders = self
            .msg_senders
            .lock()
            .expect("The message topic is poisoned");
        msg_senders.insert(msg_send.channel_id(), msg_send);

        msg_recv
    }

    pub(crate) fn destroy_message_channel(
        &self,
        msg_recv: MessageReceiver,
    ) -> Result<(), MessageTopicError> {
        let mut msg_senders = self
            .msg_senders
            .lock()
            .expect("The message topic is poisoned");
        msg_senders
            .remove(&msg_recv.channel_id())
            .map(|_| ())
            .ok_or(MessageTopicError::ChannelNotFound)
    }

    pub(crate) fn send_message(&self, msg: Arc<dyn Message>) -> Result<(), MessageTopicError> {
        let msg_senders = self
            .msg_senders
            .lock()
            .expect("The message topic is poisoned");
        msg_senders
            .values()
            .filter(|msg_send| msg_send.is_active())
            .try_for_each(|msg_send| msg_send.send(Arc::clone(&msg)))
            .map_err(|msg_channel_err| MessageTopicError::MessageChannelError(msg_channel_err))
    }
}

pub enum MessageTopicError {
    MessageChannelError(MessageChannelError),
    WrongMessageType,
    ChannelNotFound,
}