use crate::notifications::{Key, ValidatedNotification};
use crate::Error;
use async_trait::async_trait;
use dyn_clone::DynClone;
use std::any::Any;
use std::collections::{HashMap, HashSet};
use std::fmt::Debug;
use tokio::sync::{broadcast, watch};
#[cfg(feature = "discord")]
pub mod discord;
#[cfg(feature = "email")]
pub mod email;
#[cfg(feature = "file")]
pub mod file;
#[cfg(feature = "matrix")]
pub mod matrix;
#[typetag::deserialize(tag = "type")]
pub trait EndpointConfig: Debug {
fn to_endpoint(&self) -> Result<Box<dyn Endpoint + Send>, Error>;
}
#[async_trait]
pub trait Endpoint: DynClone + Send + Debug {
async fn notify(
&self,
endpoint_rx: broadcast::Receiver<ValidatedNotification>,
shutdown: watch::Receiver<bool>,
) -> Result<(), Error>;
fn generate_keys(&self, hash_key: &Key) -> HashMap<String, HashSet<Key>>;
fn as_any(&self) -> &dyn Any;
}
dyn_clone::clone_trait_object!(Endpoint);
#[derive(Clone)]
pub(crate) struct EndpointChannel {
endpoint: Box<dyn Endpoint + Send>,
channel: broadcast::Sender<ValidatedNotification>,
keys: HashMap<String, HashSet<Key>>,
}
impl EndpointChannel {
pub fn from(
endpoint: Box<dyn Endpoint + Send>,
channel: broadcast::Sender<ValidatedNotification>,
keys: HashMap<String, HashSet<Key>>,
) -> Self {
EndpointChannel { endpoint, channel, keys }
}
pub fn endpoint(&self) -> &Box<dyn Endpoint + Send> {
&self.endpoint
}
pub fn channel_receiver(&self) -> broadcast::Receiver<ValidatedNotification> {
self.channel.subscribe()
}
pub fn channel_sender(&self) -> broadcast::Sender<ValidatedNotification> {
self.channel.clone()
}
pub fn keys(&self) -> &HashMap<String, HashSet<Key>> {
&self.keys
}
}
pub(crate) async fn setup_endpoints(
endpoints: Vec<EndpointChannel>,
shutdown: watch::Receiver<bool>,
) -> Result<(), Error> {
for channel in endpoints {
channel.endpoint().notify(channel.channel_receiver(), shutdown.clone()).await?
}
Ok(())
}