use super::{
Observer,
Subject,
};
use crate::prelude::*;
use std::{
borrow::BorrowMut,
cell::RefCell,
collections::HashSet,
hash::Hash,
};
pub trait HashSetObserver = Observer + Eq + Hash;
pub struct HashSubject<O>
where
O: HashSetObserver,
{
listeners: HashSet<O>,
}
impl<O> Default for HashSubject<O>
where
O: HashSetObserver,
{
fn default() -> HashSubject<O>
{
Self::new(HashSet::default())
}
}
impl<O> HashSubject<O>
where
O: HashSetObserver,
{
#[must_use]
pub fn new(listeners: HashSet<O>) -> HashSubject<O>
{
HashSubject { listeners }
}
}
impl<O> AttachableSubject<O> for HashSubject<O>
where
O: HashSetObserver,
{
fn attach(
&mut self,
attach_observer: O,
)
{
self.listeners.borrow_mut().insert(attach_observer);
}
}
#[derive(Debug)]
pub enum DetachError
{
ObserverNotFound,
}
impl<O> DetachableSubject<O, DetachError> for HashSubject<O>
where
O: HashSetObserver,
{
fn detach(
&mut self,
detach_observer: &O,
) -> Result<(), DetachError>
{
if self.listeners.remove(detach_observer) {
Ok(())
} else {
Err(DetachError::ObserverNotFound)
}
}
}
impl<O> Subject for HashSubject<O>
where
O: HashSetObserver,
{
fn notify(&self)
{
self.listeners.iter().for_each(Observer::notify);
}
}