Mountain/ApplicationState/State/FeatureState/Diagnostics/
DiagnosticsState.rs

1//! # DiagnosticsState Module (ApplicationState)
2//!
3//! ## RESPONSIBILITIES
4//! Manages diagnostic errors state including markers organized by owner and
5//! resource URI. Supports multiple diagnostic owners with their respective
6//! marker collections.
7//!
8//! ## ARCHITECTURAL ROLE
9//! DiagnosticsState is part of the **FeatureState** module, representing
10//! diagnostic errors state.
11//!
12//! ## KEY COMPONENTS
13//! - DiagnosticsState: Main struct containing diagnostics map
14//! - Default: Initialization implementation
15//! - Helper methods: Diagnostics manipulation utilities
16//!
17//! ## ERROR HANDLING
18//! - Thread-safe access via `Arc<Mutex<...>>`
19//! - Proper lock error handling with `MapLockError` helpers
20//!
21//! ## LOGGING
22//! State changes are logged at appropriate levels (debug, info, warn, error).
23//!
24//! ## PERFORMANCE CONSIDERATIONS
25//! - Lock mutexes briefly and release immediately
26//! - Avoid nested locks to prevent deadlocks
27//! - Use Arc for shared ownership across threads
28//!
29//! ## TODO
30//! - [ ] Add diagnostics validation invariants
31//! - [ ] Implement diagnostics change events
32//! - [ ] Add diagnostics metrics collection
33
34use std::{
35	collections::HashMap,
36	sync::{Arc, Mutex as StandardMutex},
37};
38
39use log::debug;
40
41use crate::ApplicationState::DTO::MarkerDataDTO::MarkerDataDTO;
42
43/// Diagnostic errors state containing markers by owner and resource.
44#[derive(Clone)]
45pub struct DiagnosticsState {
46	/// Diagnostics map organized by owner and resource URI.
47	///
48	/// Structure: owner -> resource URI -> list of markers
49	pub DiagnosticsMap:Arc<StandardMutex<HashMap<String, HashMap<String, Vec<MarkerDataDTO>>>>>,
50}
51
52impl Default for DiagnosticsState {
53	fn default() -> Self {
54		debug!("[DiagnosticsState] Initializing default diagnostics state...");
55
56		Self { DiagnosticsMap:Arc::new(StandardMutex::new(HashMap::new())) }
57	}
58}
59
60impl DiagnosticsState {
61	/// Gets all diagnostics for all owners and resources.
62	pub fn GetAll(&self) -> HashMap<String, HashMap<String, Vec<MarkerDataDTO>>> {
63		self.DiagnosticsMap.lock().ok().map(|guard| guard.clone()).unwrap_or_default()
64	}
65
66	/// Gets all diagnostics for a specific owner.
67	pub fn GetByOwner(&self, owner:&str) -> HashMap<String, Vec<MarkerDataDTO>> {
68		self.DiagnosticsMap
69			.lock()
70			.ok()
71			.and_then(|guard| guard.get(owner).cloned())
72			.unwrap_or_default()
73	}
74
75	/// Gets all diagnostics for a specific owner and resource.
76	pub fn GetByOwnerAndResource(&self, owner:&str, resource:&str) -> Vec<MarkerDataDTO> {
77		self.DiagnosticsMap
78			.lock()
79			.ok()
80			.and_then(|guard| guard.get(owner).and_then(|resources| resources.get(resource).cloned()))
81			.unwrap_or_default()
82	}
83
84	/// Sets all diagnostics for a specific owner.
85	pub fn SetByOwner(&self, owner:String, diagnostics:HashMap<String, Vec<MarkerDataDTO>>) {
86		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
87			guard.insert(owner, diagnostics);
88			debug!("[DiagnosticsState] Diagnostics updated for owner");
89		}
90	}
91
92	/// Sets diagnostics for a specific owner and resource.
93	pub fn SetByOwnerAndResource(&self, owner:String, resource:String, markers:Vec<MarkerDataDTO>) {
94		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
95			guard.entry(owner).or_insert_with(HashMap::new).insert(resource, markers);
96			debug!("[DiagnosticsState] Diagnostics updated for owner and resource");
97		}
98	}
99
100	/// Clears all diagnostics for a specific owner.
101	pub fn ClearByOwner(&self, owner:&str) {
102		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
103			guard.remove(owner);
104			debug!("[DiagnosticsState] Diagnostics cleared for owner: {}", owner);
105		}
106	}
107
108	/// Clears diagnostics for a specific owner and resource.
109	pub fn ClearByOwnerAndResource(&self, owner:&str, resource:&str) {
110		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
111			if let Some(resources) = guard.get_mut(owner) {
112				resources.remove(resource);
113				debug!("[DiagnosticsState] Diagnostics cleared for owner and resource");
114			}
115		}
116	}
117
118	/// Clears all diagnostics.
119	pub fn ClearAll(&self) {
120		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
121			guard.clear();
122			debug!("[DiagnosticsState] All diagnostics cleared");
123		}
124	}
125}