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			dev_log!("extensions", "[DiagnosticsState] Diagnostics updated for owner");
87		}
88	}
89
90	/// Sets diagnostics for a specific owner and resource.
91	pub fn SetByOwnerAndResource(&self, owner:String, resource:String, markers:Vec<MarkerDataDTO>) {
92		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
93			guard.entry(owner).or_insert_with(HashMap::new).insert(resource, markers);
94			dev_log!("extensions", "[DiagnosticsState] Diagnostics updated for owner and resource");
95		}
96	}
97
98	/// Clears all diagnostics for a specific owner.
99	pub fn ClearByOwner(&self, owner:&str) {
100		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
101			guard.remove(owner);
102			dev_log!("extensions", "[DiagnosticsState] Diagnostics cleared for owner: {}", owner);
103		}
104	}
105
106	/// Clears diagnostics for a specific owner and resource.
107	pub fn ClearByOwnerAndResource(&self, owner:&str, resource:&str) {
108		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
109			if let Some(resources) = guard.get_mut(owner) {
110				resources.remove(resource);
111				dev_log!("extensions", "[DiagnosticsState] Diagnostics cleared for owner and resource");
112			}
113		}
114	}
115
116	/// Clears all diagnostics.
117	pub fn ClearAll(&self) {
118		if let Ok(mut guard) = self.DiagnosticsMap.lock() {
119			guard.clear();
120			dev_log!("extensions", "[DiagnosticsState] All diagnostics cleared");
121		}
122	}
123}