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}