217 lines
5.8 KiB
Rust
Raw Normal View History

//! Registry for managing ecosystem integrations
use crate::ecosystem::{EcosystemIntegration, EcosystemIntegrationError, IntegrationMetadata};
use std::collections::HashMap;
use std::sync::Arc;
use tracing::{debug, info};
/// Registry for ecosystem integrations
pub struct IntegrationRegistry {
integrations: HashMap<String, Arc<dyn EcosystemIntegration>>,
}
impl IntegrationRegistry {
/// Create a new empty registry
pub fn new() -> Self {
Self {
integrations: HashMap::new(),
}
}
/// Register an integration
pub fn register(
&mut self,
integration: Arc<dyn EcosystemIntegration>,
) -> Result<(), EcosystemIntegrationError> {
let name = integration.name().to_string();
if self.integrations.contains_key(&name) {
return Err(EcosystemIntegrationError::IntegrationError(format!(
"Integration '{}' already registered",
name
)));
}
info!("Registering ecosystem integration: {}", name);
self.integrations.insert(name, integration);
Ok(())
}
/// Get an integration by name
pub fn get(
&self,
name: &str,
) -> Result<Arc<dyn EcosystemIntegration>, EcosystemIntegrationError> {
self.integrations.get(name).map(|i| Arc::clone(i)).ok_or(
EcosystemIntegrationError::NotFound {
name: name.to_string(),
},
)
}
/// Get all registered integrations
pub fn all(&self) -> Vec<Arc<dyn EcosystemIntegration>> {
self.integrations.values().cloned().collect()
}
/// Get all available integrations (those that are configured and available)
pub fn available(&self) -> Vec<Arc<dyn EcosystemIntegration>> {
self.integrations
.values()
.filter(|i| i.is_available())
.cloned()
.collect()
}
/// Get metadata for all integrations
pub fn metadata(&self) -> Vec<IntegrationMetadata> {
self.integrations.values().map(|i| i.metadata()).collect()
}
/// Check if integration is registered
pub fn has(&self, name: &str) -> bool {
self.integrations.contains_key(name)
}
/// Get number of registered integrations
pub fn count(&self) -> usize {
self.integrations.len()
}
/// Get number of available integrations
pub fn available_count(&self) -> usize {
self.integrations
.values()
.filter(|i| i.is_available())
.count()
}
/// Unregister an integration
pub fn unregister(&mut self, name: &str) -> Result<(), EcosystemIntegrationError> {
if self.integrations.remove(name).is_some() {
info!("Unregistered ecosystem integration: {}", name);
Ok(())
} else {
Err(EcosystemIntegrationError::NotFound {
name: name.to_string(),
})
}
}
/// Clear all registrations
pub fn clear(&mut self) {
debug!("Clearing all ecosystem integrations");
self.integrations.clear();
}
}
impl Default for IntegrationRegistry {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use async_trait::async_trait;
struct TestIntegration {
name: String,
}
#[async_trait]
impl EcosystemIntegration for TestIntegration {
fn name(&self) -> &str {
&self.name
}
}
#[test]
fn test_registry_register() {
let mut registry = IntegrationRegistry::new();
let integration = Arc::new(TestIntegration {
name: "test".to_string(),
});
assert!(registry.register(integration).is_ok());
assert!(registry.has("test"));
assert_eq!(registry.count(), 1);
}
#[test]
fn test_registry_duplicate_registration() {
let mut registry = IntegrationRegistry::new();
let integration = Arc::new(TestIntegration {
name: "test".to_string(),
});
assert!(registry.register(integration.clone()).is_ok());
assert!(registry.register(integration).is_err());
}
#[test]
fn test_registry_get() {
let mut registry = IntegrationRegistry::new();
let integration = Arc::new(TestIntegration {
name: "test".to_string(),
});
registry.register(integration).unwrap();
let retrieved = registry.get("test").unwrap();
assert_eq!(retrieved.name(), "test");
}
#[test]
fn test_registry_get_not_found() {
let registry = IntegrationRegistry::new();
assert!(registry.get("nonexistent").is_err());
}
#[test]
fn test_registry_unregister() {
let mut registry = IntegrationRegistry::new();
let integration = Arc::new(TestIntegration {
name: "test".to_string(),
});
registry.register(integration).unwrap();
assert_eq!(registry.count(), 1);
assert!(registry.unregister("test").is_ok());
assert_eq!(registry.count(), 0);
assert!(!registry.has("test"));
}
#[test]
fn test_registry_clear() {
let mut registry = IntegrationRegistry::new();
for i in 0..3 {
let integration = Arc::new(TestIntegration {
name: format!("test{}", i),
});
registry.register(integration).unwrap();
}
assert_eq!(registry.count(), 3);
registry.clear();
assert_eq!(registry.count(), 0);
}
#[test]
fn test_registry_metadata() {
let mut registry = IntegrationRegistry::new();
let integration = Arc::new(TestIntegration {
name: "test".to_string(),
});
registry.register(integration).unwrap();
let metadata = registry.metadata();
assert_eq!(metadata.len(), 1);
assert_eq!(metadata[0].name, "test");
}
}