use super::{
AttachablePublisher,
DetachablePublisher,
};
use crate::prelude::*;
use core::marker::PhantomData;
use std::{
cell::RefCell,
fmt::Debug,
};
pub struct VecPublisher<M, S>
where
S: Subscriber<M>,
{
listeners: Vec<S>,
_retain_types: PhantomData<M>,
}
#[derive(Debug)]
pub enum DetachError
{
SubscriberNotFound,
}
impl<M, S> Debug for VecPublisher<M, S>
where
S: Subscriber<M> + Debug,
{
fn fmt(
&self,
f: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result
{
f.debug_struct("VecPublisher")
.field("listeners", &self.listeners)
.finish()
}
}
impl<M, S> Default for VecPublisher<M, S>
where
S: Subscriber<M>,
{
fn default() -> Self
{
Self::new(Vec::default())
}
}
impl<M, S> VecPublisher<M, S>
where
S: Subscriber<M>,
{
#[must_use]
pub fn new(listeners: Vec<S>) -> VecPublisher<M, S>
{
VecPublisher {
listeners,
_retain_types: PhantomData,
}
}
}
impl<M, S> Publisher<M> for VecPublisher<M, S>
where
S: Subscriber<M>,
{
fn publish(
&self,
message: &M,
)
{
self.listeners.iter().for_each(|s| s.receive(message));
}
}
impl<M, S> DetachablePublisher<M, S, DetachError> for VecPublisher<M, S>
where
S: Subscriber<M> + Eq,
{
fn detach(
&mut self,
detach_subscriber: &S,
) -> Result<(), DetachError>
{
let (i, _) = self
.listeners
.iter()
.enumerate()
.find(|(_, o)| o.eq(&detach_subscriber))
.ok_or(DetachError::SubscriberNotFound)?;
self.listeners.swap_remove(i);
Ok(())
}
}
impl<M, S> AttachablePublisher<M, S> for VecPublisher<M, S>
where
S: Subscriber<M>,
{
fn attach(
&mut self,
attach_subscriber: S,
)
{
self.listeners.push(attach_subscriber);
}
}