Mountain/ApplicationState/State/UIState/
UIState.rs

1//! # UIState Module (ApplicationState)
2//!
3//! ## RESPONSIBILITIES
4//! Manages user interface request state including pending UI interactions
5//! such as dialogs, prompts, and other synchronous UI requests. Uses
6//! oneshot channels for request/response communication.
7//!
8//! ## ARCHITECTURAL ROLE
9//! UIState is part of the **state organization layer**, representing
10//! user interface request state organized by request ID.
11//!
12//! ## KEY COMPONENTS
13//! - State: Main struct containing pending UI requests map
14//! - Default: Initialization implementation
15//! - Helper methods: UI request 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//! - Use oneshot channels for request/response
29//!
30//! ## TODO
31//! - [ ] Add UI request validation invariants
32//! - [ ] Implement UI request timeout handling
33//! - [ ] Add UI request metrics collection
34
35use std::{
36	collections::HashMap,
37	sync::{Arc, Mutex as StandardMutex},
38};
39
40use CommonLibrary::Error::CommonError::CommonError;
41use log::debug;
42
43/// User interface request state containing pending UI interactions.
44#[derive(Clone)]
45pub struct State {
46	/// Pending user interface requests organized by request ID.
47	///
48	/// Each request has a oneshot sender for sending the response back.
49	pub PendingUserInterfaceRequests:
50		Arc<StandardMutex<HashMap<String, tokio::sync::oneshot::Sender<Result<serde_json::Value, CommonError>>>>>,
51}
52
53impl Default for State {
54	fn default() -> Self {
55		debug!("[UIState] Initializing default UI state...");
56
57		Self { PendingUserInterfaceRequests:Arc::new(StandardMutex::new(HashMap::new())) }
58	}
59}
60
61impl State {
62	/// Gets all pending user interface request IDs.
63	/// Note: Returns only the IDs since oneshot::Sender cannot be cloned.
64	pub fn GetPendingRequests(&self) -> Vec<String> {
65		self.PendingUserInterfaceRequests
66			.lock()
67			.ok()
68			.map(|guard| guard.keys().cloned().collect())
69			.unwrap_or_default()
70	}
71
72	/// Adds a pending user interface request.
73	pub fn AddPendingRequest(
74		&self,
75		id:String,
76		sender:tokio::sync::oneshot::Sender<Result<serde_json::Value, CommonError>>,
77	) {
78		if let Ok(mut guard) = self.PendingUserInterfaceRequests.lock() {
79			guard.insert(id, sender);
80			debug!("[UIState] Pending UI request added");
81		}
82	}
83
84	/// Removes a pending user interface request by its ID.
85	pub fn RemovePendingRequest(
86		&self,
87		id:&str,
88	) -> Option<tokio::sync::oneshot::Sender<Result<serde_json::Value, CommonError>>> {
89		if let Ok(mut guard) = self.PendingUserInterfaceRequests.lock() {
90			let sender = guard.remove(id);
91			debug!("[UIState] Pending UI request removed: {}", id);
92			sender
93		} else {
94			None
95		}
96	}
97
98	/// Clears all pending user interface requests.
99	pub fn ClearAll(&self) {
100		if let Ok(mut guard) = self.PendingUserInterfaceRequests.lock() {
101			guard.clear();
102			debug!("[UIState] All pending UI requests cleared");
103		}
104	}
105
106	/// Gets the count of pending user interface requests.
107	pub fn Count(&self) -> usize {
108		self.PendingUserInterfaceRequests
109			.lock()
110			.ok()
111			.map(|guard| guard.len())
112			.unwrap_or(0)
113	}
114
115	/// Checks if a pending user interface request exists.
116	pub fn Contains(&self, id:&str) -> bool {
117		self.PendingUserInterfaceRequests
118			.lock()
119			.ok()
120			.map(|guard| guard.contains_key(id))
121			.unwrap_or(false)
122	}
123}