Skip to main content

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;
41
42use crate::dev_log;
43
44/// User interface request state containing pending UI interactions.
45#[derive(Clone)]
46pub struct State {
47	/// Pending user interface request organized by request ID.
48	///
49	/// Each request has a oneshot sender for sending the response back.
50	pub PendingUserInterfaceRequest:
51		Arc<StandardMutex<HashMap<String, tokio::sync::oneshot::Sender<Result<serde_json::Value, CommonError>>>>>,
52}
53
54impl Default for State {
55	fn default() -> Self {
56		dev_log!("window", "[UIState] Initializing default UI state...");
57
58		Self { PendingUserInterfaceRequest:Arc::new(StandardMutex::new(HashMap::new())) }
59	}
60}
61
62impl State {
63	/// Gets all pending user interface request IDs.
64	/// Note: Returns only the IDs since oneshot::Sender cannot be cloned.
65	pub fn GetPendingRequests(&self) -> Vec<String> {
66		self.PendingUserInterfaceRequest
67			.lock()
68			.ok()
69			.map(|guard| guard.keys().cloned().collect())
70			.unwrap_or_default()
71	}
72
73	/// Adds a pending user interface request.
74	pub fn AddPendingRequest(
75		&self,
76		id:String,
77		sender:tokio::sync::oneshot::Sender<Result<serde_json::Value, CommonError>>,
78	) {
79		if let Ok(mut guard) = self.PendingUserInterfaceRequest.lock() {
80			guard.insert(id, sender);
81			dev_log!("window", "[UIState] Pending UI request added");
82		}
83	}
84
85	/// Removes a pending user interface request by its ID.
86	pub fn RemovePendingRequest(
87		&self,
88		id:&str,
89	) -> Option<tokio::sync::oneshot::Sender<Result<serde_json::Value, CommonError>>> {
90		if let Ok(mut guard) = self.PendingUserInterfaceRequest.lock() {
91			let sender = guard.remove(id);
92			dev_log!("window", "[UIState] Pending UI request removed: {}", id);
93			sender
94		} else {
95			None
96		}
97	}
98
99	/// Clears all pending user interface requests.
100	pub fn ClearAll(&self) {
101		if let Ok(mut guard) = self.PendingUserInterfaceRequest.lock() {
102			guard.clear();
103			dev_log!("window", "[UIState] All pending UI requests cleared");
104		}
105	}
106
107	/// Gets the count of pending user interface requests.
108	pub fn Count(&self) -> usize {
109		self.PendingUserInterfaceRequest
110			.lock()
111			.ok()
112			.map(|guard| guard.len())
113			.unwrap_or(0)
114	}
115
116	/// Checks if a pending user interface request exists.
117	pub fn Contains(&self, id:&str) -> bool {
118		self.PendingUserInterfaceRequest
119			.lock()
120			.ok()
121			.map(|guard| guard.contains_key(id))
122			.unwrap_or(false)
123	}
124}