mockforge_core/scenarios/
registry.rs1use crate::scenarios::types::ScenarioDefinition;
4use crate::{Error, Result};
5use std::collections::HashMap;
6use std::sync::Arc;
7use tokio::sync::RwLock;
8
9#[derive(Debug, Clone)]
11pub struct ScenarioRegistry {
12 scenarios: Arc<RwLock<HashMap<String, ScenarioDefinition>>>,
14}
15
16impl ScenarioRegistry {
17 pub fn new() -> Self {
19 Self {
20 scenarios: Arc::new(RwLock::new(HashMap::new())),
21 }
22 }
23
24 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 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 pub async fn list(&self) -> Vec<ScenarioDefinition> {
39 let scenarios = self.scenarios.read().await;
40 scenarios.values().cloned().collect()
41 }
42
43 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 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 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}