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 = "camelCase")]
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
65 ProviderType:ProviderType,
66
67 Selector:Value,
68
69 SideCarIdentifier:String,
70
71 ExtensionIdentifier:Value,
72 ) -> Result<Self, String> {
73 // Validate sidecar identifier length
74 if SideCarIdentifier.len() > MAX_SIDECAR_IDENTIFIER_LENGTH {
75 return Err(format!(
76 "SideCarIdentifier exceeds maximum length of {} bytes",
77 MAX_SIDECAR_IDENTIFIER_LENGTH
78 ));
79 }
80
81 Ok(Self {
82 Handle,
83 ProviderType,
84 Selector,
85 SideCarIdentifier,
86 ExtensionIdentifier,
87 Options:None,
88 })
89 }
90
91 /// Updates the provider options.
92 ///
93 /// # Arguments
94 /// * `Options` - New options value
95 pub fn UpdateOptions(&mut self, Options:Value) { self.Options = Some(Options); }
96
97 /// Checks if this provider matches a given document selector.
98 ///
99 /// # Arguments
100 /// * `DocumentURI` - Document URI to check
101 /// * `LanguageIdentifier` - Document language identifier
102 ///
103 /// # Returns
104 /// True if provider selector matches the document
105 pub fn MatchesSelector(&self, _DocumentURI:&str, LanguageIdentifier:&str) -> bool {
106 // This is a simplified matching logic
107 // A full implementation would traverse the selector value
108 if let Some(SelectorObj) = self.Selector.as_object() {
109 if let Some(Languages) = SelectorObj.get("language").and_then(Value::as_array) {
110 return Languages
111 .iter()
112 .any(|Lang| Lang.as_str().map_or(false, |L| L == LanguageIdentifier));
113 }
114 }
115
116 false
117 }
118}