use service_channel::oneshot;
pub trait Topic: Send + 'static {
type Item: Clone + Send + 'static;
}
pub trait RoutedTopic<S>: Topic
where
S: crate::Service,
{
fn endpoint(service: &mut S) -> &mut TopicEndpoint<Self>
where
Self: Sized;
}
pub struct TopicEndpoint<T>
where
T: Topic,
{
waiters: Vec<oneshot::Sender<T::Item>>,
}
impl<T> Default for TopicEndpoint<T>
where
T: Topic,
{
fn default() -> Self {
Self {
waiters: Vec::new(),
}
}
}
impl<T> TopicEndpoint<T>
where
T: Topic,
{
pub fn subscribe(&mut self, tx: oneshot::Sender<T::Item>) {
self.waiters.push(tx);
}
pub fn publish(&mut self, item: T::Item) {
let waiters = std::mem::take(&mut self.waiters);
for tx in waiters {
let _ = tx.send(item.clone());
}
}
pub fn len(&self) -> usize {
self.waiters.len()
}
pub fn is_empty(&self) -> bool {
self.waiters.is_empty()
}
pub fn clear(&mut self) {
self.waiters.clear();
}
}