Mountain/ApplicationState/DTO/
ProviderRegistrationDTO.rs

1//! # ProviderRegistrationDTO
2//!
3//! # RESPONSIBILITY
4//! - Data transfer object for language feature provider registration
5//! - Serializable format for gRPC/IPC transmission
6//! - Used by Mountain to track active language feature providers
7//!
8//! # FIELDS
9//! - Handle: Unique registration handle
10//! - ProviderType: Type of feature provider
11//! - Selector: Document selector value
12//! - SideCarIdentifier: Host sidecar process ID
13//! - ExtensionIdentifier: Contributor extension ID
14//! - Options: Provider-specific options
15use CommonLibrary::LanguageFeature::DTO::ProviderType::ProviderType;
16use serde::{Deserialize, Serialize};
17use serde_json::Value;
18
19/// Maximum sidecar identifier length
20const MAX_SIDECAR_IDENTIFIER_LENGTH:usize = 128;
21
22/// Stores the registration details for a single language feature provider
23/// contributed by an extension. This is stored in `ApplicationState` to track
24/// all active providers.
25#[derive(Serialize, Deserialize, Debug, Clone)]
26#[serde(rename_all = "PascalCase")]
27pub struct ProviderRegistrationDTO {
28	/// A unique handle for this registration, generated by Mountain.
29	pub Handle:u32,
30
31	/// The type of feature this provider implements.
32	pub ProviderType:ProviderType,
33
34	/// The document selector (serialized as a `Value`) that determines which
35	/// documents this provider applies to.
36	pub Selector:Value,
37
38	/// The identifier of the sidecar process that hosts this provider's logic.
39	#[serde(skip_serializing_if = "String::is_empty")]
40	pub SideCarIdentifier:String,
41
42	/// The identifier of the extension that contributed this provider.
43	pub ExtensionIdentifier:Value,
44
45	/// Optional, feature-specific options for this provider.
46	#[serde(skip_serializing_if = "Option::is_none")]
47	pub Options:Option<Value>,
48}
49
50impl ProviderRegistrationDTO {
51	/// Creates a new ProviderRegistrationDTO with validation.
52	///
53	/// # Arguments
54	/// * `Handle` - Unique registration handle
55	/// * `ProviderType` - Type of feature provider
56	/// * `Selector` - Document selector value
57	/// * `SideCarIdentifier` - Sidecar process identifier
58	/// * `ExtensionIdentifier` - Extension identifier value
59	///
60	/// # Returns
61	/// Result containing the DTO or validation error
62	pub fn New(
63		Handle:u32,
64		ProviderType:ProviderType,
65		Selector:Value,
66		SideCarIdentifier:String,
67		ExtensionIdentifier:Value,
68	) -> Result<Self, String> {
69		// Validate sidecar identifier length
70		if SideCarIdentifier.len() > MAX_SIDECAR_IDENTIFIER_LENGTH {
71			return Err(format!(
72				"SideCarIdentifier exceeds maximum length of {} bytes",
73				MAX_SIDECAR_IDENTIFIER_LENGTH
74			));
75		}
76
77		Ok(Self {
78			Handle,
79			ProviderType,
80			Selector,
81			SideCarIdentifier,
82			ExtensionIdentifier,
83			Options:None,
84		})
85	}
86
87	/// Updates the provider options.
88	///
89	/// # Arguments
90	/// * `Options` - New options value
91	pub fn UpdateOptions(&mut self, Options:Value) { self.Options = Some(Options); }
92
93	/// Checks if this provider matches a given document selector.
94	///
95	/// # Arguments
96	/// * `DocumentURI` - Document URI to check
97	/// * `LanguageIdentifier` - Document language identifier
98	///
99	/// # Returns
100	/// True if provider selector matches the document
101	pub fn MatchesSelector(&self, _DocumentURI:&str, LanguageIdentifier:&str) -> bool {
102		// This is a simplified matching logic
103		// A full implementation would traverse the selector value
104		if let Some(SelectorObj) = self.Selector.as_object() {
105			if let Some(Languages) = SelectorObj.get("language").and_then(Value::as_array) {
106				return Languages
107					.iter()
108					.any(|Lang| Lang.as_str().map_or(false, |L| L == LanguageIdentifier));
109			}
110		}
111		false
112	}
113}