use std::fmt::Debug; use super::{Component, ComponentContext, Handler}; use async_trait::async_trait; use thiserror::Error; // Message Wrapper #[derive(Debug)] pub(crate) struct Wrapper where C: Component, { wrapper: Box>, } impl Wrapper { pub(super) async fn handle(&mut self, component: &mut C, ctx: &ComponentContext) -> () { self.wrapper.handle(component, ctx).await; } } #[async_trait] pub(super) trait WrapperTrait: Debug + Send where C: Component, { async fn handle(&mut self, component: &mut C, ctx: &ComponentContext) -> (); } #[async_trait] impl WrapperTrait for Option where C: Component + Handler, M: Debug + Send + 'static, { async fn handle(&mut self, component: &mut C, ctx: &ComponentContext) -> () { if let Some(message) = self.take() { component.handle(message, ctx).await; } } } pub(crate) fn wrap(message: M) -> Wrapper where C: Component + Handler, M: Debug + Send + 'static, { Wrapper { wrapper: Box::new(Some(message)), } } // Sender pub(crate) struct Sender where C: Component + Send + 'static, { pub(super) sender: tokio::sync::mpsc::Sender>, } impl Sender where C: Component + Send + 'static, { pub(super) fn new(sender: tokio::sync::mpsc::Sender>) -> Self { Sender { sender } } pub(crate) async fn send(&self, message: M) -> Result<(), ChannelError> where C: Component + Handler, M: Debug + Send + 'static, { let res = self.sender.send(wrap(message)).await; match res { Ok(_) => Ok(()), Err(_) => Err(ChannelError::SendError), } } } impl Clone for Sender where C: Component, { fn clone(&self) -> Self { Sender { sender: self.sender.clone(), } } } // Reciever Traits #[async_trait] pub(crate) trait Receiver: Send + Sync + ReceiverClone { async fn send(&self, message: M) -> Result<(), ChannelError>; } trait ReceiverClone { fn clone_box(&self) -> Box>; } impl Clone for Box> { fn clone(&self) -> Box> { self.clone_box() } } impl ReceiverClone for T where T: 'static + Receiver + Clone, { fn clone_box(&self) -> Box> { Box::new(self.clone()) } } // Reciever Impls pub(super) struct ReceiverImpl where C: Component, { pub(super) sender: tokio::sync::mpsc::Sender>, } impl Clone for ReceiverImpl where C: Component, { fn clone(&self) -> Self { ReceiverImpl { sender: self.sender.clone(), } } } impl ReceiverImpl where C: Component, { pub(super) fn new(sender: tokio::sync::mpsc::Sender>) -> Self { ReceiverImpl { sender } } } #[async_trait] impl Receiver for ReceiverImpl where C: Component + Handler, M: Send + Debug + 'static, { async fn send(&self, message: M) -> Result<(), ChannelError> { let res = self.sender.send(wrap(message)).await; match res { Ok(_) => Ok(()), Err(_) => Err(ChannelError::SendError), } } } // Errors #[derive(Error, Debug)] pub enum ChannelError { #[error("Failed to send message")] SendError, }