Skip to main content

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 crate::{ApplicationState::DTO::MarkerDataDTO::MarkerDataDTO, dev_log};
40
41/// Diagnostic errors state containing markers by owner and resource.
42#[derive(Clone)]
43pub struct DiagnosticsState {
44	/// Diagnostics map organized by owner and resource URI.
45	///
46	/// Structure: owner -> resource URI -> list of markers
47	pub DiagnosticsMap:Arc<StandardMutex<HashMap<String, HashMap<String, Vec<MarkerDataDTO>>>>>,
48}
49
50impl Default for DiagnosticsState {
51	fn default() -> Self {
52		dev_log!("extensions", "[DiagnosticsState] Initializing default diagnostics state...");
53
54		Self { DiagnosticsMap:Arc::new(StandardMutex::new(HashMap::new())) }
55	}
56}
57
58impl DiagnosticsState {
59	/// Gets all diagnostics for all owners and resources.
60	pub fn GetAll(&self) -> HashMap<String, HashMap<String, Vec<MarkerDataDTO>>> {
61		self.DiagnosticsMap.lock().ok().map(|guard| guard.clone()).unwrap_or_default()
62	}
63
64	/// Gets all diagnostics for a specific owner.
65	pub fn GetByOwner(&self, owner:&str) -> HashMap<String, Vec<MarkerDataDTO>> {
66		self.DiagnosticsMap
67			.lock()
68			.ok()
69			.and_then(|guard| guard.get(owner).cloned())
70			.unwrap_or_default()
71	}
72
73	/// Gets all diagnostics for a specific owner and resource.
74	pub fn GetByOwnerAndResource(&self, owner:&str, resource:&str) -> Vec<MarkerDataDTO> {
75		self.DiagnosticsMap
76			.lock()
77			.ok()
78			.and_then(|guard| guard.get(owner).and_then(|resources| resources.get(resource).cloned()))
79			.unwrap_or_default()
80	}
81
82	/// Sets all diagnostics for a specific owner.
83	pub fn SetByOwner(&self, owner:String, diagnostics:HashMap<String, Vec<MarkerDataDTO>>) {
84		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
85			guard.insert(owner, diagnostics);
86
87			dev_log!("extensions", "[DiagnosticsState] Diagnostics updated for owner");
88		}
89	}
90
91	/// Sets diagnostics for a specific owner and resource.
92	pub fn SetByOwnerAndResource(&self, owner:String, resource:String, markers:Vec<MarkerDataDTO>) {
93		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
94			guard.entry(owner).or_insert_with(HashMap::new).insert(resource, markers);
95
96			dev_log!("extensions", "[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
105			dev_log!("extensions", "[DiagnosticsState] Diagnostics cleared for owner: {}", owner);
106		}
107	}
108
109	/// Clears diagnostics for a specific owner and resource.
110	pub fn ClearByOwnerAndResource(&self, owner:&str, resource:&str) {
111		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
112			if let Some(resources) = guard.get_mut(owner) {
113				resources.remove(resource);
114
115				dev_log!("extensions", "[DiagnosticsState] Diagnostics cleared for owner and resource");
116			}
117		}
118	}
119
120	/// Clears all diagnostics.
121	pub fn ClearAll(&self) {
122		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
123			guard.clear();
124
125			dev_log!("extensions", "[DiagnosticsState] All diagnostics cleared");
126		}
127	}
128}