mockforge_core/scenarios/
registry.rs

1//! Scenario registry for storing and retrieving scenario definitions
2
3use crate::scenarios::types::ScenarioDefinition;
4use crate::{Error, Result};
5use std::collections::HashMap;
6use std::sync::Arc;
7use tokio::sync::RwLock;
8
9/// Registry for managing scenario definitions
10#[derive(Debug, Clone)]
11pub struct ScenarioRegistry {
12    /// Storage for scenario definitions (scenario_id -> ScenarioDefinition)
13    scenarios: Arc<RwLock<HashMap<String, ScenarioDefinition>>>,
14}
15
16impl ScenarioRegistry {
17    /// Create a new scenario registry
18    pub fn new() -> Self {
19        Self {
20            scenarios: Arc::new(RwLock::new(HashMap::new())),
21        }
22    }
23
24    /// Register a scenario definition
25    pub async fn register(&self, scenario: ScenarioDefinition) -> Result<()> {
26        let mut scenarios = self.scenarios.write().await;
27        scenarios.insert(scenario.id.clone(), scenario);
28        Ok(())
29    }
30
31    /// Get a scenario by ID
32    pub async fn get(&self, scenario_id: &str) -> Option<ScenarioDefinition> {
33        let scenarios = self.scenarios.read().await;
34        scenarios.get(scenario_id).cloned()
35    }
36
37    /// List all registered scenarios
38    pub async fn list(&self) -> Vec<ScenarioDefinition> {
39        let scenarios = self.scenarios.read().await;
40        scenarios.values().cloned().collect()
41    }
42
43    /// Search scenarios by name or tag
44    pub async fn search(&self, query: &str) -> Vec<ScenarioDefinition> {
45        let scenarios = self.scenarios.read().await;
46        let query_lower = query.to_lowercase();
47        scenarios
48            .values()
49            .filter(|scenario| {
50                scenario.name.to_lowercase().contains(&query_lower)
51                    || scenario.id.to_lowercase().contains(&query_lower)
52                    || scenario.tags.iter().any(|tag| tag.to_lowercase().contains(&query_lower))
53                    || scenario
54                        .description
55                        .as_ref()
56                        .map(|d| d.to_lowercase().contains(&query_lower))
57                        .unwrap_or(false)
58            })
59            .cloned()
60            .collect()
61    }
62
63    /// Remove a scenario
64    pub async fn remove(&self, scenario_id: &str) -> bool {
65        let mut scenarios = self.scenarios.write().await;
66        scenarios.remove(scenario_id).is_some()
67    }
68
69    /// Clear all scenarios
70    pub async fn clear(&self) {
71        let mut scenarios = self.scenarios.write().await;
72        scenarios.clear();
73    }
74}
75
76impl Default for ScenarioRegistry {
77    fn default() -> Self {
78        Self::new()
79    }
80}