use std::collections::HashMap;
use std::sync::Arc;
type Decoder<E> = Arc<dyn Fn(&[u8]) -> Result<E, String> + Send + Sync + 'static>;
pub struct EventCodecRegistry<E: Send + 'static> {
pub(crate) decoders: HashMap<String, Decoder<E>>,
pub(crate) default: Option<Decoder<E>>,
}
impl<E: Send + 'static> Default for EventCodecRegistry<E> {
fn default() -> Self {
Self { decoders: HashMap::new(), default: None }
}
}
impl<E: Send + 'static> EventCodecRegistry<E> {
pub fn new() -> Self {
Self::default()
}
pub fn register<F>(mut self, manifest: impl Into<String>, decode: F) -> Self
where
F: Fn(&[u8]) -> Result<E, String> + Send + Sync + 'static,
{
self.decoders.insert(manifest.into(), Arc::new(decode));
self
}
pub fn with_default<F>(mut self, decode: F) -> Self
where
F: Fn(&[u8]) -> Result<E, String> + Send + Sync + 'static,
{
self.default = Some(Arc::new(decode));
self
}
pub fn decode(&self, manifest: &str, bytes: &[u8]) -> Option<Result<E, String>> {
if let Some(decoder) = self.decoders.get(manifest) {
return Some(decoder(bytes));
}
self.default.as_ref().map(|d| d(bytes))
}
}