omni_director/providers/
feature_registry.rs

1//! # Feature Registry
2//!
3//! Manages feature interface definitions (not callable providers)
4//! Features define the minimum API surface that CPIs must implement
5
6use std::collections::HashMap;
7
8/// Feature interface definition
9#[derive(Debug, Clone)]
10pub struct FeatureInterface {
11    pub name: String,
12    pub description: String,
13    pub operations: Vec<FeatureOperation>,
14}
15
16/// Operation definition within a feature
17#[derive(Debug, Clone)]
18pub struct FeatureOperation {
19    pub name: String,
20    pub description: String,
21    pub parameters: HashMap<String, ParameterDefinition>,
22    pub returns: Option<String>,
23}
24
25/// Parameter definition for an operation
26#[derive(Debug, Clone)]
27pub struct ParameterDefinition {
28    pub name: String,
29    pub param_type: String,
30    pub required: bool,
31    pub description: Option<String>,
32}
33
34/// Registry for feature interface definitions
35pub struct FeatureRegistry {
36    features: HashMap<String, FeatureInterface>,
37}
38
39impl FeatureRegistry {
40    /// Create a new feature registry
41    pub fn new() -> Self {
42        Self {
43            features: HashMap::new(),
44        }
45    }
46    
47    /// Register a feature interface
48    pub fn register_feature(&mut self, feature: FeatureInterface) {
49        self.features.insert(feature.name.clone(), feature);
50    }
51    
52    /// Get a feature interface by name
53    pub fn get_feature(&self, name: &str) -> Option<&FeatureInterface> {
54        self.features.get(name)
55    }
56    
57    /// List all registered features
58    pub fn list_features(&self) -> Vec<&str> {
59        self.features.keys().map(|s| s.as_str()).collect()
60    }
61    
62    /// Validate that a provider implements a feature correctly
63    pub fn validate_provider_feature(
64        &self,
65        provider_name: &str,
66        feature_name: &str,
67        provider_operations: &[String],
68    ) -> Result<(), String> {
69        let feature = self.get_feature(feature_name)
70            .ok_or_else(|| format!("Feature '{}' not found", feature_name))?;
71        
72        // Check that provider implements all required operations
73        for op in &feature.operations {
74            if !provider_operations.contains(&op.name) {
75                return Err(format!(
76                    "Provider '{}' missing required operation '{}' for feature '{}'",
77                    provider_name, op.name, feature_name
78                ));
79            }
80        }
81        
82        Ok(())
83    }
84    
85    /// Get operation definition for a feature
86    pub fn get_operation_definition(
87        &self,
88        feature_name: &str,
89        operation_name: &str,
90    ) -> Option<&FeatureOperation> {
91        self.features.get(feature_name)?
92            .operations.iter()
93            .find(|op| op.name == operation_name)
94    }
95}
96
97impl Default for FeatureRegistry {
98    fn default() -> Self {
99        Self::new()
100    }
101}