Mountain/ApplicationState/DTO/TreeViewStateDTO.rs
1//! # TreeViewStateDTO
2//!
3//! # RESPONSIBILITY
4//! - Data transfer object for tree view state
5//! - In-memory state tracking (not serializable due to trait object)
6//! - Used by Mountain to track tree view provider instances
7//!
8//! # FIELDS
9//! - ViewIdentifier: Unique tree view identifier
10//! - Provider: Native Rust provider reference
11//! - SideCarIdentifier: Extension sidecar host ID
12//! - CanSelectMany: Multi-selection support flag
13//! - HasHandleDrag: Drag-and-drop source support
14//! - HasHandleDrop: Drop target support
15//! - Message: Optional UI message
16//! - Title: Tree view title
17//! - Description: Optional description text
18
19use std::sync::Arc;
20
21use CommonLibrary::TreeView::TreeViewProvider::TreeViewProvider;
22
23/// Maximum view identifier length
24const MAX_VIEW_IDENTIFIER_LENGTH:usize = 128;
25
26/// Maximum sidecar identifier length
27const MAX_SIDECAR_IDENTIFIER_LENGTH:usize = 128;
28
29/// Maximum message length
30const MAX_MESSAGE_LENGTH:usize = 1024;
31
32/// Maximum title length
33const MAX_TITLE_LENGTH:usize = 256;
34
35/// Maximum description length
36const MAX_DESCRIPTION_LENGTH:usize = 512;
37
38/// Holds the static options and provider for a tree view instance that has been
39/// registered by an extension or natively. This is stored in `ApplicationState`
40/// to track active tree views.
41///
42/// This struct holds references to either a native (Rust) provider or metadata
43/// for a proxied (extension) provider.
44///
45/// NOTE: This struct does not derive Serialize/Deserialize because `Arc<dyn
46/// ...>` is not serializable. It is intended for in-memory state management
47/// only.
48#[derive(Clone)]
49pub struct TreeViewStateDTO {
50 /// The unique identifier for this tree view.
51 pub ViewIdentifier:String,
52
53 /// A reference to the native provider, if one exists for this view.
54 /// This will be `None` for extension-provided (proxied) tree views.
55 pub Provider:Option<Arc<dyn TreeViewProvider + Send + Sync>>,
56
57 /// The identifier of the sidecar process that hosts the provider logic.
58 /// This will be `Some` for extension-provided (proxied) tree views.
59 pub SideCarIdentifier:Option<String>,
60
61 /// Whether the tree view supports selecting multiple items.
62 pub CanSelectMany:bool,
63
64 /// Whether the tree view supports drag and drop for its items.
65 pub HasHandleDrag:bool,
66
67 /// Whether the tree view supports dropping items onto it.
68 pub HasHandleDrop:bool,
69
70 /// An optional message to display in the tree view's UI.
71 pub Message:Option<String>,
72
73 /// The title of the tree view.
74 pub Title:Option<String>,
75
76 /// An optional description that appears with the title.
77 pub Description:Option<String>,
78}
79
80impl TreeViewStateDTO {
81 /// Creates a new TreeViewStateDTO with validation.
82 ///
83 /// # Arguments
84 /// * `ViewIdentifier` - Unique view identifier
85 /// * `Provider` - Optional native provider
86 /// * `SideCarIdentifier` - Optional sidecar identifier
87 /// * `CanSelectMany` - Multi-selection support
88 /// * `HasHandleDrag` - Drag support
89 /// * `HasHandleDrop` - Drop support
90 ///
91 /// # Returns
92 /// Result containing the DTO or validation error
93 pub fn New(
94 ViewIdentifier:String,
95 Provider:Option<Arc<dyn TreeViewProvider + Send + Sync>>,
96 SideCarIdentifier:Option<String>,
97 CanSelectMany:bool,
98 HasHandleDrag:bool,
99 HasHandleDrop:bool,
100 ) -> Result<Self, String> {
101 // Validate view identifier length
102 if ViewIdentifier.len() > MAX_VIEW_IDENTIFIER_LENGTH {
103 return Err(format!(
104 "View identifier exceeds maximum length of {} bytes",
105 MAX_VIEW_IDENTIFIER_LENGTH
106 ));
107 }
108
109 // Validate sidecar identifier length
110 if let Some(SideCarID) = &SideCarIdentifier {
111 if SideCarID.len() > MAX_SIDECAR_IDENTIFIER_LENGTH {
112 return Err(format!(
113 "SideCar identifier exceeds maximum length of {} bytes",
114 MAX_SIDECAR_IDENTIFIER_LENGTH
115 ));
116 }
117 }
118
119 Ok(Self {
120 ViewIdentifier,
121 Provider,
122 SideCarIdentifier,
123 CanSelectMany,
124 HasHandleDrag,
125 HasHandleDrop,
126 Message:None,
127 Title:None,
128 Description:None,
129 })
130 }
131
132 /// Sets the UI message with validation.
133 ///
134 /// # Arguments
135 /// * `Message` - Message text
136 ///
137 /// # Returns
138 /// Result indicating success or error if message too long
139 pub fn SetMessage(&mut self, Message:String) -> Result<(), String> {
140 if Message.len() > MAX_MESSAGE_LENGTH {
141 return Err(format!("Message exceeds maximum length of {} bytes", MAX_MESSAGE_LENGTH));
142 }
143
144 self.Message = Some(Message);
145 Ok(())
146 }
147
148 /// Sets the title with validation.
149 ///
150 /// # Arguments
151 /// * `Title` - Title text
152 ///
153 /// # Returns
154 /// Result indicating success or error if title too long
155 pub fn SetTitle(&mut self, Title:String) -> Result<(), String> {
156 if Title.len() > MAX_TITLE_LENGTH {
157 return Err(format!("Title exceeds maximum length of {} bytes", MAX_TITLE_LENGTH));
158 }
159
160 self.Title = Some(Title);
161 Ok(())
162 }
163
164 /// Sets the description with validation.
165 ///
166 /// # Arguments
167 /// * `Description` - Description text
168 ///
169 /// # Returns
170 /// Result indicating success or error if description too long
171 pub fn SetDescription(&mut self, Description:String) -> Result<(), String> {
172 if Description.len() > MAX_DESCRIPTION_LENGTH {
173 return Err(format!(
174 "Description exceeds maximum length of {} bytes",
175 MAX_DESCRIPTION_LENGTH
176 ));
177 }
178
179 self.Description = Some(Description);
180 Ok(())
181 }
182
183 /// Checks if this is a native (Rust) tree view.
184 pub fn IsNative(&self) -> bool { self.Provider.is_some() }
185
186 /// Checks if this is a proxy (extension) tree view.
187 pub fn IsProxy(&self) -> bool { self.SideCarIdentifier.is_some() }
188}