use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use futures::{Stream, future::BoxFuture};
use crate::Result;
pub trait Publisher {
type Message: Send + 'static;
fn get_name(&self) -> &'static str;
fn publish(&self, message: Self::Message) -> BoxFuture<Result<()>>;
fn get_message_stream(
&mut self,
subscriber_name: &'static str,
) -> Result<Pin<Box<dyn Stream<Item = Self::Message> + Send + Sync + 'static>>>;
}
impl<T> Publisher for T
where
T: Deref + DerefMut,
T::Target: Publisher,
{
type Message = <T::Target as Publisher>::Message;
fn get_name(&self) -> &'static str {
self.deref().get_name()
}
fn publish(&self, message: Self::Message) -> BoxFuture<Result<()>> {
self.deref().publish(message)
}
fn get_message_stream(
&mut self,
subscriber_name: &'static str,
) -> Result<Pin<Box<dyn Stream<Item = Self::Message> + Send + Sync + 'static>>> {
self.deref_mut().get_message_stream(subscriber_name)
}
}
pub trait PublisherWrapper<Message>
where
Message: Send + 'static,
{
fn get_publisher(&self) -> &dyn Publisher<Message = Message>;
fn get_publisher_mut(&mut self) -> &mut dyn Publisher<Message = Message>;
fn get_name(&self) -> &'static str {
Publisher::get_name(self.get_publisher())
}
fn publish(&self, message: Message) -> futures::future::BoxFuture<Result<()>> {
Publisher::publish(self.get_publisher(), message)
}
fn get_message_stream(
&mut self,
subscriber_name: &'static str,
) -> Result<std::pin::Pin<Box<dyn futures::Stream<Item = Message> + Send + Sync + 'static>>>
{
Publisher::get_message_stream(self.get_publisher_mut(), subscriber_name)
}
}
impl<T> PublisherWrapper<T::Message> for T
where
T: Publisher,
{
fn get_publisher(&self) -> &dyn Publisher<Message = T::Message> {
self
}
fn get_publisher_mut(&mut self) -> &mut dyn Publisher<Message = T::Message> {
self
}
}