//! 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>, } 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, ) -> 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, EcosystemIntegrationError> { self.integrations.get(name).map(Arc::clone).ok_or( EcosystemIntegrationError::NotFound { name: name.to_string(), }, ) } /// Get all registered integrations pub fn all(&self) -> Vec> { self.integrations.values().cloned().collect() } /// Get all available integrations (those that are configured and available) pub fn available(&self) -> Vec> { self.integrations .values() .filter(|i| i.is_available()) .cloned() .collect() } /// Get metadata for all integrations pub fn metadata(&self) -> Vec { 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"); } }