use crate::guardian::error::{GuardianError, Result};
use crate::traits::{DirectChannelEmitter, EventPubSub, EventPubSubMessage, EventPubSubPayload};
use async_trait::async_trait;
use iroh::NodeId;
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::{RwLock, broadcast};
pub mod messaging;
pub mod network;
#[derive(Clone)]
pub struct EventBus {
channels: Arc<RwLock<HashMap<TypeId, Box<dyn Any + Send + Sync>>>>,
}
impl Default for EventBus {
fn default() -> Self {
Self::new()
}
}
impl EventBus {
pub fn new() -> Self {
Self {
channels: Arc::new(RwLock::new(HashMap::new())),
}
}
pub async fn emitter<T>(&self) -> Result<Emitter<T>>
where
T: Clone + Send + Sync + 'static,
{
let type_id = TypeId::of::<T>();
let mut channels = self.channels.write().await;
channels.entry(type_id).or_insert_with(|| {
let (sender, _) = broadcast::channel::<T>(1024); Box::new(sender)
});
let sender = channels
.get(&type_id)
.and_then(|any| any.downcast_ref::<broadcast::Sender<T>>())
.ok_or_else(|| GuardianError::Other("Failed to get sender for type".to_string()))?
.clone();
Ok(Emitter { sender })
}
pub async fn subscribe<T>(&self) -> Result<broadcast::Receiver<T>>
where
T: Clone + Send + Sync + 'static,
{
let type_id = TypeId::of::<T>();
let mut channels = self.channels.write().await;
channels.entry(type_id).or_insert_with(|| {
let (sender, _) = broadcast::channel::<T>(1024);
Box::new(sender)
});
let sender = channels
.get(&type_id)
.and_then(|any| any.downcast_ref::<broadcast::Sender<T>>())
.ok_or_else(|| GuardianError::Other("Failed to get sender for type".to_string()))?;
Ok(sender.subscribe())
}
}
pub struct Emitter<T> {
sender: broadcast::Sender<T>,
}
impl<T> Emitter<T>
where
T: Clone + Send + Sync + 'static,
{
pub fn emit(&self, event: T) -> Result<()> {
let _ = self.sender.send(event);
Ok(())
}
pub fn receiver_count(&self) -> usize {
self.sender.receiver_count()
}
pub async fn close(&self) -> Result<()> {
Ok(())
}
}
pub type Bus = EventBus;
pub struct PayloadEmitter {
emitter: Emitter<EventPubSubPayload>,
}
impl PayloadEmitter {
pub async fn new(bus: &Bus) -> Result<Self> {
let emitter = bus.emitter::<EventPubSubPayload>().await?;
Ok(PayloadEmitter { emitter })
}
pub fn emit_payload(&self, evt: EventPubSubPayload) -> Result<()> {
self.emitter.emit(evt)
}
}
#[async_trait]
impl DirectChannelEmitter for PayloadEmitter {
type Error = GuardianError;
async fn emit(&self, payload: EventPubSubPayload) -> std::result::Result<(), Self::Error> {
self.emit_payload(payload)
}
async fn close(&self) -> std::result::Result<(), Self::Error> {
Ok(())
}
}
pub fn new_event_message(content: Vec<u8>) -> EventPubSubMessage {
EventPubSubMessage { content }
}
pub fn new_event_payload(payload: Vec<u8>, peer: NodeId) -> EventPubSubPayload {
EventPubSubPayload { payload, peer }
}
pub fn new_event_peer_join(peer: NodeId, topic: String) -> EventPubSub {
EventPubSub::Join { peer, topic }
}
pub fn new_event_peer_leave(peer: NodeId, topic: String) -> EventPubSub {
EventPubSub::Leave { peer, topic }
}