use super::{Error, LocalCapabilityEntry, SharedCapabilityEntry};
use otel_arrow_dfe_config::ExtensionId;
use std::any::TypeId;
use std::collections::HashMap;
pub struct CapabilityRegistry {
local: HashMap<TypeId, HashMap<ExtensionId, LocalCapabilityEntry>>,
shared: HashMap<TypeId, HashMap<ExtensionId, SharedCapabilityEntry>>,
}
impl CapabilityRegistry {
#[must_use]
pub fn new() -> Self {
CapabilityRegistry {
local: HashMap::new(),
shared: HashMap::new(),
}
}
pub fn register_local(
&mut self,
capability_id: TypeId,
entry: LocalCapabilityEntry,
) -> Result<(), Error> {
let ext_id = entry.extension_id.clone();
let slot = self.local.entry(capability_id).or_default();
if slot.contains_key(&ext_id) {
return Err(Error::InternalError {
message: format!(
"duplicate local capability registration: extension '{ext_id}' already registered capability TypeId {capability_id:?}",
),
});
}
let _ = slot.insert(ext_id, entry);
Ok(())
}
pub fn register_shared(
&mut self,
capability_id: TypeId,
entry: SharedCapabilityEntry,
) -> Result<(), Error> {
let ext_id = entry.extension_id.clone();
let slot = self.shared.entry(capability_id).or_default();
if slot.contains_key(&ext_id) {
return Err(Error::InternalError {
message: format!(
"duplicate shared capability registration: extension '{ext_id}' already registered capability TypeId {capability_id:?}",
),
});
}
let _ = slot.insert(ext_id, entry);
Ok(())
}
#[must_use]
pub fn get_local(
&self,
capability_id: &TypeId,
extension_id: &str,
) -> Option<&LocalCapabilityEntry> {
self.local
.get(capability_id)
.and_then(|m| m.get(extension_id))
}
#[must_use]
pub fn get_shared(
&self,
capability_id: &TypeId,
extension_id: &str,
) -> Option<&SharedCapabilityEntry> {
self.shared
.get(capability_id)
.and_then(|m| m.get(extension_id))
}
#[must_use]
pub(crate) fn has_native_local(&self, capability_id: &TypeId) -> bool {
self.local.get(capability_id).is_some_and(|m| !m.is_empty())
}
#[must_use]
pub(crate) fn has_shared(&self, capability_id: &TypeId) -> bool {
self.shared
.get(capability_id)
.is_some_and(|m| !m.is_empty())
}
}
impl Default for CapabilityRegistry {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for CapabilityRegistry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CapabilityRegistry")
.field("local_capabilities", &self.local.len())
.field("shared_capabilities", &self.shared.len())
.finish()
}
}