darpan 0.2.5

Linux developer service monitoring utility with auto-detection, real-time health checks, and interactive TUI for databases, APIs, Docker containers, and more
Documentation
use crate::config::ProjectConfig;
use crate::detectors::DetectorTrait;
use crate::models::Service;
use anyhow::Result;
use std::collections::HashMap;
use std::path::Path;
use tracing::debug;

/// Registry for service detectors
pub struct DetectorRegistry {
    detectors: HashMap<String, Box<dyn DetectorTrait>>,
    enabled: Vec<String>,
}

impl DetectorRegistry {
    pub fn new() -> Self {
        Self {
            detectors: HashMap::new(),
            enabled: Vec::new(),
        }
    }

    /// Register a detector with a unique identifier
    pub fn register(&mut self, id: String, detector: Box<dyn DetectorTrait>) {
        debug!("Registering detector: {}", id);
        self.detectors.insert(id.clone(), detector);
    }

    /// Enable detectors by their IDs
    pub fn enable(&mut self, ids: Vec<String>) {
        self.enabled = ids;
    }

    /// Get all enabled detectors, sorted by priority
    pub fn get_enabled(&self) -> Vec<&dyn DetectorTrait> {
        let mut enabled_detectors: Vec<(&String, &dyn DetectorTrait)> = self
            .detectors
            .iter()
            .filter(|(id, _)| self.enabled.contains(id))
            .map(|(id, detector)| (id, detector.as_ref()))
            .collect();

        // Sort by priority (higher priority first)
        enabled_detectors.sort_by(|a, b| b.1.priority().cmp(&a.1.priority()));

        enabled_detectors.into_iter().map(|(_, detector)| detector).collect()
    }

    /// Detect services using all enabled detectors
    pub async fn detect(
        &self,
        project_path: &Path,
        config: Option<&ProjectConfig>,
    ) -> Result<Vec<Service>> {
        let mut all_services = Vec::new();

        for detector in self.get_enabled() {
            debug!("Running detector: {}", detector.name());
            let services = detector.detect(project_path, config).await?;
            debug!("Detector {} found {} services", detector.name(), services.len());
            all_services.extend(services);
        }

        Ok(all_services)
    }

    /// Check if a detector is registered
    pub fn is_registered(&self, id: &str) -> bool {
        self.detectors.contains_key(id)
    }

    /// Get list of all registered detector IDs
    pub fn registered_ids(&self) -> Vec<String> {
        self.detectors.keys().cloned().collect()
    }
}

impl Default for DetectorRegistry {
    fn default() -> Self {
        Self::new()
    }
}