use std::collections::HashMap;
use std::sync::Arc;
use thiserror::Error;
use super::handler::JobHandler;
#[derive(Debug, Error)]
pub enum RegistryError {
#[error("duplicate handler kind: {0}")]
Duplicate(String),
}
#[derive(Clone)]
pub struct HandlerRegistry {
inner: Arc<HashMap<String, Arc<dyn JobHandler>>>,
}
impl HandlerRegistry {
pub fn from_handlers<I>(handlers: I) -> Result<Self, RegistryError>
where
I: IntoIterator<Item = Arc<dyn JobHandler>>,
{
let mut map: HashMap<String, Arc<dyn JobHandler>> = HashMap::new();
for h in handlers {
let kind = h.kind().to_string();
if map.contains_key(&kind) {
return Err(RegistryError::Duplicate(kind));
}
map.insert(kind, h);
}
Ok(Self {
inner: Arc::new(map),
})
}
pub fn get(&self, kind: &str) -> Option<Arc<dyn JobHandler>> {
self.inner.get(kind).cloned()
}
pub fn kinds(&self) -> Vec<String> {
self.inner.keys().cloned().collect()
}
pub fn max_concurrent(&self, kind: &str) -> usize {
self.inner
.get(kind)
.and_then(|h| h.max_concurrent())
.unwrap_or(0)
}
}
#[derive(Default)]
pub struct HandlerRegistryBuilder {
handlers: Vec<Arc<dyn JobHandler>>,
}
impl HandlerRegistryBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn register(mut self, handler: Arc<dyn JobHandler>) -> Self {
self.handlers.push(handler);
self
}
pub fn build(self) -> Result<HandlerRegistry, RegistryError> {
HandlerRegistry::from_handlers(self.handlers)
}
}