Skip to main content

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/// Maximum badge length (serialized JSON)
39const MAX_BADGE_LENGTH:usize = 2048;
40
41/// Holds the static options and provider for a tree view instance that has been
42/// registered by an extension or natively. This is stored in `ApplicationState`
43/// to track active tree views.
44///
45/// This struct holds references to either a native (Rust) provider or metadata
46/// for a proxied (extension) provider.
47///
48/// NOTE: This struct does not derive Serialize/Deserialize because `Arc<dyn
49/// ...>` is not serializable. It is intended for in-memory state management
50/// only.
51#[derive(Clone)]
52pub struct TreeViewStateDTO {
53	/// The unique identifier for this tree view.
54	pub ViewIdentifier:String,
55
56	/// A reference to the native provider, if one exists for this view.
57	/// This will be `None` for extension-provided (proxied) tree views.
58	pub Provider:Option<Arc<dyn TreeViewProvider + Send + Sync>>,
59
60	/// The identifier of the sidecar process that hosts the provider logic.
61	/// This will be `Some` for extension-provided (proxied) tree views.
62	pub SideCarIdentifier:Option<String>,
63
64	/// Whether the tree view supports selecting multiple items.
65	pub CanSelectMany:bool,
66
67	/// Whether the tree view supports drag and drop for its items.
68	pub HasHandleDrag:bool,
69
70	/// Whether the tree view supports dropping items onto it.
71	pub HasHandleDrop:bool,
72
73	/// An optional message to display in the tree view's UI.
74	pub Message:Option<String>,
75
76	/// The title of the tree view.
77	pub Title:Option<String>,
78
79	/// An optional description that appears with the title.
80	pub Description:Option<String>,
81
82	/// Badge to display on the tree view (typically a count or string)
83	pub Badge:Option<String>,
84}
85
86impl TreeViewStateDTO {
87	/// Creates a new TreeViewStateDTO with validation.
88	///
89	/// # Arguments
90	/// * `ViewIdentifier` - Unique view identifier
91	/// * `Provider` - Optional native provider
92	/// * `SideCarIdentifier` - Optional sidecar identifier
93	/// * `CanSelectMany` - Multi-selection support
94	/// * `HasHandleDrag` - Drag support
95	/// * `HasHandleDrop` - Drop support
96	///
97	/// # Returns
98	/// Result containing the DTO or validation error
99	pub fn New(
100		ViewIdentifier:String,
101		Provider:Option<Arc<dyn TreeViewProvider + Send + Sync>>,
102		SideCarIdentifier:Option<String>,
103		CanSelectMany:bool,
104		HasHandleDrag:bool,
105		HasHandleDrop:bool,
106	) -> Result<Self, String> {
107		// Validate view identifier length
108		if ViewIdentifier.len() > MAX_VIEW_IDENTIFIER_LENGTH {
109			return Err(format!(
110				"View identifier exceeds maximum length of {} bytes",
111				MAX_VIEW_IDENTIFIER_LENGTH
112			));
113		}
114
115		// Validate sidecar identifier length
116		if let Some(SideCarID) = &SideCarIdentifier {
117			if SideCarID.len() > MAX_SIDECAR_IDENTIFIER_LENGTH {
118				return Err(format!(
119					"SideCar identifier exceeds maximum length of {} bytes",
120					MAX_SIDECAR_IDENTIFIER_LENGTH
121				));
122			}
123		}
124
125		Ok(Self {
126			ViewIdentifier,
127			Provider,
128			SideCarIdentifier,
129			CanSelectMany,
130			HasHandleDrag,
131			HasHandleDrop,
132			Message:None,
133			Title:None,
134			Description:None,
135			Badge:None,
136		})
137	}
138
139	/// Sets the UI message with validation.
140	///
141	/// # Arguments
142	/// * `Message` - Message text
143	///
144	/// # Returns
145	/// Result indicating success or error if message too long
146	pub fn SetMessage(&mut self, Message:String) -> Result<(), String> {
147		if Message.len() > MAX_MESSAGE_LENGTH {
148			return Err(format!("Message exceeds maximum length of {} bytes", MAX_MESSAGE_LENGTH));
149		}
150
151		self.Message = Some(Message);
152		Ok(())
153	}
154
155	/// Sets the title with validation.
156	///
157	/// # Arguments
158	/// * `Title` - Title text
159	///
160	/// # Returns
161	/// Result indicating success or error if title too long
162	pub fn SetTitle(&mut self, Title:String) -> Result<(), String> {
163		if Title.len() > MAX_TITLE_LENGTH {
164			return Err(format!("Title exceeds maximum length of {} bytes", MAX_TITLE_LENGTH));
165		}
166
167		self.Title = Some(Title);
168		Ok(())
169	}
170
171	/// Sets the description with validation.
172	///
173	/// # Arguments
174	/// * `Description` - Description text
175	///
176	/// # Returns
177	/// Result indicating success or error if description too long
178	pub fn SetDescription(&mut self, Description:String) -> Result<(), String> {
179		if Description.len() > MAX_DESCRIPTION_LENGTH {
180			return Err(format!(
181				"Description exceeds maximum length of {} bytes",
182				MAX_DESCRIPTION_LENGTH
183			));
184		}
185
186		self.Description = Some(Description);
187		Ok(())
188	}
189
190	/// Sets the badge with validation.
191	///
192	/// # Arguments
193	/// * `Badge` - Badge value (typically a count or string)
194	///
195	/// # Returns
196	/// Result indicating success or error if badge too long
197	pub fn SetBadge(&mut self, Badge:String) -> Result<(), String> {
198		if Badge.len() > MAX_BADGE_LENGTH {
199			return Err(format!("Badge exceeds maximum length of {} bytes", MAX_BADGE_LENGTH));
200		}
201
202		self.Badge = Some(Badge);
203		Ok(())
204	}
205
206	/// Checks if this is a native (Rust) tree view.
207	pub fn IsNative(&self) -> bool { self.Provider.is_some() }
208
209	/// Checks if this is a proxy (extension) tree view.
210	pub fn IsProxy(&self) -> bool { self.SideCarIdentifier.is_some() }
211}