#[cfg(feature = "blocking")]
use std::{
collections::HashMap,
hash::Hash,
sync::{Arc, Mutex},
};
#[cfg(feature = "tokio")]
use std::{collections::HashMap, hash::Hash, sync::Arc};
#[cfg(feature = "tokio")]
use tokio::sync::Mutex;
mod queue;
#[cfg(feature = "blocking")]
mod blocking;
#[cfg(feature = "tokio")]
mod tokio_impl;
#[cfg(feature = "blocking")]
use blocking::Subscriber;
#[cfg(feature = "tokio")]
use tokio_impl::Subscriber;
#[cfg(feature = "blocking")]
pub struct PicoPub<T, U>
where
T: ToString + Eq + PartialEq + Hash,
U: Clone,
{
topics: Mutex<HashMap<T, Vec<Arc<Subscriber<U>>>>>,
}
#[cfg(feature = "tokio")]
pub struct PicoPub<T, U>
where
T: ToString + Eq + PartialEq + Hash + Sync + Send,
U: Clone + Sync + Send + 'static,
{
topics: Mutex<HashMap<T, Vec<Arc<Subscriber<U>>>>>,
}
impl<T, U> PicoPub<T, U>
where
T: ToString + Eq + PartialEq + Hash + Sync + Send,
U: Clone + Sync + Send + 'static,
{
pub fn new() -> Self {
Self {
topics: Mutex::new(HashMap::new()),
}
}
#[cfg(feature = "blocking")]
pub fn subscribe(&self, topic: T, throttle: Option<usize>) -> Arc<Subscriber<U>> {
let cap = throttle.unwrap_or(0);
let mut topics = self.topics.lock().unwrap();
let sub = Arc::new(Subscriber::<U>::new(cap));
topics.entry(topic).or_default().push(sub.clone());
sub
}
#[cfg(feature = "tokio")]
pub async fn subscribe(&self, topic: T, throttle: Option<usize>) -> Arc<Subscriber<U>> {
let cap = throttle.unwrap_or(0);
let mut topics = self.topics.lock().await;
let sub = Arc::new(Subscriber::<U>::new(cap));
topics.entry(topic).or_default().push(sub.clone());
sub
}
#[cfg(feature = "blocking")]
pub fn publish(&self, topic: T, msg: U) {
let topics = self.topics.lock().unwrap();
let data = Arc::new(msg);
if let Some(subs) = topics.get(&topic) {
for sub in subs {
sub.push(data.clone())
}
}
}
#[cfg(feature = "tokio")]
pub async fn publish(&self, topic: T, msg: U) {
let topics = self.topics.lock().await;
let data = Arc::new(msg);
if let Some(subs) = topics.get(&topic) {
for sub in subs {
sub.push(data.clone()).await;
}
}
}
}
impl<T, U> Default for PicoPub<T, U>
where
T: ToString + Eq + PartialEq + Hash + Sync + Send,
U: Clone + Sync + Send + 'static,
{
fn default() -> Self {
Self::new()
}
}