use std::{
future::Future,
sync::{Arc, RwLock, Weak},
};
pub trait ResFut<'a, R, E>: Future<Output = Result<R, E>> + Send + 'a {}
impl<'a, R, E, T: Future<Output = Result<R, E>> + Send + 'a> ResFut<'a, R, E> for T {}
pub struct Subscribers<T: ?Sized + Send + Sync + 'static> {
receivers: Arc<RwLock<Vec<Weak<T>>>>,
}
impl<T: ?Sized + Send + Sync + 'static> Clone for Subscribers<T> {
fn clone(&self) -> Self {
Self {
receivers: Arc::clone(&self.receivers),
}
}
}
impl<T: ?Sized + Send + Sync + 'static> Subscribers<T> {
pub fn new() -> Self {
Self {
receivers: Arc::new(RwLock::new(vec![])),
}
}
pub fn register(&self, subscriber: Arc<T>) {
let weak = Arc::downgrade(&subscriber);
let mut receivers = self.receivers.write().expect("lock poisoned");
receivers.retain(|r| r.strong_count() > 0);
receivers.push(weak);
}
pub fn for_each(&self, mut f: impl FnMut(&T)) {
let receivers = self.receivers.read().expect("lock poisoned");
for receiver in receivers.iter() {
if let Some(receiver) = receiver.upgrade() {
f(&*receiver);
}
}
}
}
impl<T: ?Sized + Send + Sync + 'static> Default for Subscribers<T> {
fn default() -> Self {
Self::new()
}
}