use alloc::vec::Vec; use hashbrown::HashMap; use std::sync::mpsc; use crate::{ mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, Submode}, queue::GenericTargetedMessagingError, request::{ MessageReceiver, MessageReceiverWithId, MessageSender, MessageSenderAndReceiver, MessageSenderMap, MessageSenderMapWithId, MessageWithSenderId, RequestAndReplySenderAndReceiver, }, ChannelId, }; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum TableEntryType { /// Target table containing information of the expected children modes for given mode. Target, /// Sequence table which contains information about how to reach a target table, including /// the order of the sequences. Sequence, } pub struct ModeTableEntry { /// Name of respective table entry. pub name: &'static str, /// Target channel ID. pub channel_id: ChannelId, pub mode_submode: ModeAndSubmode, pub allowed_submode_mask: Option, pub check_success: bool, } pub struct ModeTableMapValue { /// Name for a given mode table entry. pub name: &'static str, pub entries: Vec, } pub type ModeTable = HashMap; pub trait ModeRequestSender { fn local_channel_id(&self) -> ChannelId; fn send_mode_request( &self, target_id: ChannelId, request: ModeRequest, ) -> Result<(), GenericTargetedMessagingError>; } pub trait ModeReplySender { fn local_channel_id(&self) -> ChannelId; fn send_mode_reply( &self, target_id: ChannelId, reply: ModeReply, ) -> Result<(), GenericTargetedMessagingError>; } pub trait ModeRequestReceiver { fn try_recv_mode_request( &self, ) -> Result>, GenericTargetedMessagingError>; } pub trait ModeReplyReceiver { fn try_recv_mode_reply( &self, ) -> Result>, GenericTargetedMessagingError>; } impl> MessageSenderMap { pub fn send_mode_request( &self, local_id: ChannelId, target_id: ChannelId, request: ModeRequest, ) -> Result<(), GenericTargetedMessagingError> { self.send_message(local_id, target_id, request) } pub fn add_request_target(&mut self, target_id: ChannelId, request_sender: S) { self.add_message_target(target_id, request_sender) } } impl> MessageSenderMap { pub fn send_mode_reply( &self, local_id: ChannelId, target_id: ChannelId, request: ModeReply, ) -> Result<(), GenericTargetedMessagingError> { self.send_message(local_id, target_id, request) } pub fn add_reply_target(&mut self, target_id: ChannelId, request_sender: S) { self.add_message_target(target_id, request_sender) } } impl> ModeReplySender for MessageSenderMapWithId { fn send_mode_reply( &self, target_channel_id: ChannelId, reply: ModeReply, ) -> Result<(), GenericTargetedMessagingError> { self.send_message(target_channel_id, reply) } fn local_channel_id(&self) -> ChannelId { self.local_channel_id } } impl> ModeRequestSender for MessageSenderMapWithId { fn local_channel_id(&self) -> ChannelId { self.local_channel_id } fn send_mode_request( &self, target_id: ChannelId, request: ModeRequest, ) -> Result<(), GenericTargetedMessagingError> { self.send_message(target_id, request) } } impl> ModeReplyReceiver for MessageReceiverWithId { fn try_recv_mode_reply( &self, ) -> Result>, GenericTargetedMessagingError> { self.try_recv_message() } } impl> ModeRequestReceiver for MessageReceiverWithId { fn try_recv_mode_request( &self, ) -> Result>, GenericTargetedMessagingError> { self.try_recv_message() } } impl, R: MessageReceiver> ModeRequestSender for MessageSenderAndReceiver { fn local_channel_id(&self) -> ChannelId { self.local_channel_id_generic() } fn send_mode_request( &self, target_id: ChannelId, request: ModeRequest, ) -> Result<(), GenericTargetedMessagingError> { self.message_sender_map .send_mode_request(self.local_channel_id(), target_id, request) } } impl, R: MessageReceiver> ModeReplySender for MessageSenderAndReceiver { fn local_channel_id(&self) -> ChannelId { self.local_channel_id_generic() } fn send_mode_reply( &self, target_id: ChannelId, request: ModeReply, ) -> Result<(), GenericTargetedMessagingError> { self.message_sender_map .send_mode_reply(self.local_channel_id(), target_id, request) } } impl, R: MessageReceiver> ModeReplyReceiver for MessageSenderAndReceiver { fn try_recv_mode_reply( &self, ) -> Result>, GenericTargetedMessagingError> { self.message_receiver .try_recv_message(self.local_channel_id_generic()) } } impl, R: MessageReceiver> ModeRequestReceiver for MessageSenderAndReceiver { fn try_recv_mode_request( &self, ) -> Result>, GenericTargetedMessagingError> { self.message_receiver .try_recv_message(self.local_channel_id_generic()) } } pub type ModeRequestHandlerConnector = MessageSenderAndReceiver; pub type MpscModeRequestHandlerConnector = ModeRequestHandlerConnector< mpsc::Sender>, mpsc::Receiver>, >; pub type MpscBoundedModeRequestHandlerConnector = ModeRequestHandlerConnector< mpsc::SyncSender>, mpsc::Receiver>, >; pub type ModeRequestorConnector = MessageSenderAndReceiver; pub type MpscModeRequestorConnector = ModeRequestorConnector< mpsc::Sender>, mpsc::Receiver>, >; pub type MpscBoundedModeRequestorConnector = ModeRequestorConnector< mpsc::SyncSender>, mpsc::Receiver>, >; pub type ModeConnector = RequestAndReplySenderAndReceiver; pub type MpscModeConnector = ModeConnector< mpsc::Sender>, mpsc::Receiver>, mpsc::Sender>, mpsc::Receiver>, >; pub type MpscBoundedModeConnector = ModeConnector< mpsc::SyncSender>, mpsc::Receiver>, mpsc::SyncSender>, mpsc::Receiver>, >; impl< REPLY, S0: MessageSender, R0: MessageReceiver, S1: MessageSender, R1: MessageReceiver, > RequestAndReplySenderAndReceiver { pub fn add_request_target(&mut self, target_id: ChannelId, request_sender: S0) { self.request_sender_map .add_message_target(target_id, request_sender) } } impl< REQUEST, S0: MessageSender, R0: MessageReceiver, S1: MessageSender, R1: MessageReceiver, > RequestAndReplySenderAndReceiver { pub fn add_reply_target(&mut self, target_id: ChannelId, reply_sender: S1) { self.reply_sender_map .add_message_target(target_id, reply_sender) } } impl< REPLY, S0: MessageSender, R0: MessageReceiver, S1: MessageSender, R1: MessageReceiver, > ModeRequestSender for RequestAndReplySenderAndReceiver { fn local_channel_id(&self) -> ChannelId { self.local_channel_id_generic() } fn send_mode_request( &self, target_id: ChannelId, request: ModeRequest, ) -> Result<(), GenericTargetedMessagingError> { self.request_sender_map .send_mode_request(self.local_channel_id(), target_id, request) } } impl< REQUEST, S0: MessageSender, R0: MessageReceiver, S1: MessageSender, R1: MessageReceiver, > ModeReplySender for RequestAndReplySenderAndReceiver { fn local_channel_id(&self) -> ChannelId { self.local_channel_id_generic() } fn send_mode_reply( &self, target_id: ChannelId, request: ModeReply, ) -> Result<(), GenericTargetedMessagingError> { self.reply_sender_map .send_mode_reply(self.local_channel_id(), target_id, request) } } impl< REQUEST, S0: MessageSender, R0: MessageReceiver, S1: MessageSender, R1: MessageReceiver, > ModeReplyReceiver for RequestAndReplySenderAndReceiver { fn try_recv_mode_reply( &self, ) -> Result>, GenericTargetedMessagingError> { self.reply_receiver .try_recv_message(self.local_channel_id_generic()) } } impl< REPLY, S0: MessageSender, R0: MessageReceiver, S1: MessageSender, R1: MessageReceiver, > ModeRequestReceiver for RequestAndReplySenderAndReceiver { fn try_recv_mode_request( &self, ) -> Result>, GenericTargetedMessagingError> { self.request_receiver .try_recv_message(self.local_channel_id_generic()) } } pub trait ModeProvider { fn mode_and_submode(&self) -> ModeAndSubmode; } #[derive(Debug, Clone)] pub enum ModeError { Messaging(GenericTargetedMessagingError), } impl From for ModeError { fn from(value: GenericTargetedMessagingError) -> Self { Self::Messaging(value) } } pub trait ModeRequestHandler: ModeProvider { fn start_transition(&mut self, mode_and_submode: ModeAndSubmode) -> Result<(), ModeError>; fn announce_mode(&self, recursive: bool); fn handle_mode_reached(&mut self) -> Result<(), GenericTargetedMessagingError>; } #[cfg(test)] mod tests {}