use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::fmt;
use serde::Serialize;
use crate::path::Path;
use super::{EndpointError, Message, MessageSchema};
#[derive(Default)]
pub(crate) struct EventSinkInfoRegistry(HashMap<Path, EventSinkInfo>);
impl EventSinkInfoRegistry {
pub(crate) fn register<T>(&mut self, path: Path) -> Result<(), Path>
where
T: Serialize + Message + 'static,
{
self.register_any::<_>(path, T::schema)
}
pub(crate) fn register_raw(&mut self, path: Path) -> Result<(), Path> {
self.register_any::<_>(path, String::new)
}
fn register_any<F>(&mut self, path: Path, schema_gen: F) -> Result<(), Path>
where
F: Fn() -> MessageSchema + Send + Sync + 'static,
{
match self.0.entry(path) {
Entry::Vacant(s) => {
s.insert(EventSinkInfo {
event_schema_gen: Box::new(schema_gen),
});
Ok(())
}
Entry::Occupied(e) => Err(e.key().clone()),
}
}
pub(crate) fn list_sinks(&self) -> impl Iterator<Item = &Path> {
self.0.keys()
}
pub(crate) fn get_sink_schema(&self, path: &Path) -> Result<MessageSchema, EndpointError> {
self.0
.get(path)
.map(|info| (info.event_schema_gen)())
.ok_or_else(|| EndpointError::EventSinkNotFound { path: path.clone() })
}
#[cfg(feature = "server")]
pub(crate) fn list_schemas(&self) -> impl Iterator<Item = (&Path, MessageSchema)> {
self.0
.iter()
.map(|(path, info)| (path, (info.event_schema_gen)()))
}
}
impl fmt::Debug for EventSinkInfoRegistry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "EventSinkInfoRegistry ({} sinks)", self.0.len())
}
}
pub(crate) struct EventSinkInfo {
event_schema_gen: Box<dyn Fn() -> MessageSchema + Send + Sync + 'static>,
}