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}