Skip to content

Commit acb3aef

Browse files
refactor(Vine): Rename CocoonServiceServer and fix Tauri State usage
This commit continues the refinement of Mountain's Vine gRPC server and Tauri IPC infrastructure. The primary change renames `CocoonServiceServer` to `CocoonServiceImpl` across the Vine server module to better reflect its role as a concrete implementation of the `CocoonService` trait defined in the `Common` contract. The module structure is updated accordingly for clarity. The Wind-Air Tauri commands are now properly integrated into Mountain's Binary entry point by importing and registering all commands with the Tauri application handler. Additionally, critical fixes are made to the Wind-Air command parameters: all commands now correctly use `tauri::State<'_, tauri::AppHandle>` instead of taking the AppHandle by value, ensuring proper Tauri state management and resolving lifetime issues. Import paths for the `ExtensionManagementService` trait are standardized across Mountain codebase by removing redundant module name repetition, aligning with the `Common` crate's export structure. The obsolete backup file for ApplicationState is removed as part of cleanup. These changes ensure proper integration of Wind-Air functionality with Mountain's IPC layer and maintain consistency with Land's architectural patterns.
1 parent 3edd19e commit acb3aef

9 files changed

Lines changed: 252 additions & 576 deletions

File tree

Source/ApplicationState/ApplicationState.rs.bak

Lines changed: 0 additions & 538 deletions
This file was deleted.

Source/Binary.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@ use crate::{
6464
Vine,
6565
};
6666

67+
// Import Wind-Air commands
68+
use crate::IPC::WindAirCommands::{
69+
CheckForUpdates,
70+
DownloadUpdate,
71+
ApplyUpdate,
72+
DownloadFile,
73+
AuthenticateUser,
74+
IndexFiles,
75+
SearchFiles,
76+
GetAirStatus,
77+
GetAirMetrics,
78+
};
79+
6780
// =============================================================================
6881
// Debug Helpers (Highly Verbose, Low Intrusion)
6982
// =============================================================================
@@ -569,6 +582,20 @@ pub fn Fn() {
569582
// -----------------------------------------------------------------
570583
.manage(AppState.clone())
571584
// -----------------------------------------------------------------
585+
// [Boot] [Tauri] [Commands] Wind-Air commands
586+
// -----------------------------------------------------------------
587+
.invoke_handler(tauri::generate_handler![
588+
CheckForUpdates,
589+
DownloadUpdate,
590+
ApplyUpdate,
591+
DownloadFile,
592+
AuthenticateUser,
593+
IndexFiles,
594+
SearchFiles,
595+
GetAirStatus,
596+
GetAirMetrics,
597+
])
598+
// -----------------------------------------------------------------
572599
// [Lifecycle] Setup hook
573600
// -----------------------------------------------------------------
574601
.setup({

Source/Environment/MountainEnvironment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use Common::{
2626
Document::DocumentProvider::DocumentProvider,
2727
Environment::{Environment::Environment, Requires::Requires},
2828
Error::CommonError::CommonError,
29-
ExtensionManagement::ExtensionManagementService::ExtensionManagementService,
29+
ExtensionManagement::ExtensionManagementService,
3030
FileSystem::{FileSystemReader::FileSystemReader, FileSystemWriter::FileSystemWriter},
3131
IPC::IPCProvider::IPCProvider,
3232
Keybinding::KeybindingProvider::KeybindingProvider,

Source/IPC/WindAirCommands.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl AirClientWrapper {
139139
/// `UpdateInfoDTO` with update information or error message
140140
#[tauri::command]
141141
pub async fn CheckForUpdates(
142-
app_handle: tauri::AppHandle,
142+
app_handle: tauri::State<'_, tauri::AppHandle>,
143143
current_version: Option<String>,
144144
channel: Option<String>,
145145
) -> Result<UpdateInfoDTO, String> {
@@ -194,15 +194,15 @@ pub async fn CheckForUpdates(
194194
/// `DownloadResultDTO` with download status
195195
#[tauri::command]
196196
pub async fn DownloadUpdate(
197-
app_handle: tauri::AppHandle,
197+
app_handle: tauri::State<'_, tauri::AppHandle>,
198198
url: String,
199199
destination: String,
200200
checksum: Option<String>,
201201
) -> Result<DownloadResultDTO, String> {
202202
debug!("[WindAirCommands] DownloadUpdate called: {} -> {}", url, destination);
203203

204-
let air_address = get_air_address(&app_handle)?;
205-
let client = get_or_create_air_client(&app_handle, air_address).await?;
204+
let air_address = get_air_address(app_handle.inner())?;
205+
let client = get_or_create_air_client(app_handle.inner(), air_address).await?;
206206

207207
let request = DownloadRequest {
208208
request_id: uuid::Uuid::new_v4().to_string(),
@@ -246,14 +246,14 @@ pub async fn DownloadUpdate(
246246
/// Success status or error message
247247
#[tauri::command]
248248
pub async fn ApplyUpdate(
249-
app_handle: tauri::AppHandle,
249+
app_handle: tauri::State<'_, tauri::AppHandle>,
250250
update_id: String,
251251
update_path: String,
252252
) -> Result<bool, String> {
253253
debug!("[WindAirCommands] ApplyUpdate called: id={}, path={}", update_id, update_path);
254254

255-
let air_address = get_air_address(&app_handle)?;
256-
let client = get_or_create_air_client(&app_handle, air_address).await?;
255+
let air_address = get_air_address(app_handle.inner())?;
256+
let client = get_or_create_air_client(app_handle.inner(), air_address).await?;
257257

258258
// Use ApplyUpdateRequest from Air module
259259
let request = ApplyUpdateRequest {
@@ -292,7 +292,7 @@ pub async fn ApplyUpdate(
292292
/// `DownloadResultDTO` with download status
293293
#[tauri::command]
294294
pub async fn DownloadFile(
295-
app_handle: tauri::AppHandle,
295+
app_handle: tauri::State<'_, tauri::AppHandle>,
296296
url: String,
297297
destination: String,
298298
) -> Result<DownloadResultDTO, String> {
@@ -344,15 +344,15 @@ pub async fn DownloadFile(
344344
/// `AuthResponseDTO` with authentication token
345345
#[tauri::command]
346346
pub async fn AuthenticateUser(
347-
app_handle: tauri::AppHandle,
347+
app_handle: tauri::State<'_, tauri::AppHandle>,
348348
username: String,
349349
password: String,
350350
provider: String,
351351
) -> Result<AuthResponseDTO, String> {
352352
debug!("[WindAirCommands] AuthenticateUser called: {} via {}", username, provider);
353353

354-
let air_address = get_air_address(&app_handle)?;
355-
let client = get_or_create_air_client(&app_handle, air_address).await?;
354+
let air_address = get_air_address(app_handle.inner())?;
355+
let client = get_or_create_air_client(app_handle.inner(), air_address).await?;
356356

357357
let request = AuthenticationRequest {
358358
request_id: uuid::Uuid::new_v4().to_string(),
@@ -396,16 +396,16 @@ pub async fn AuthenticateUser(
396396
/// `IndexResultDTO` with indexing results
397397
#[tauri::command]
398398
pub async fn IndexFiles(
399-
app_handle: tauri::AppHandle,
399+
app_handle: tauri::State<'_, tauri::AppHandle>,
400400
path: String,
401401
patterns: Vec<String>,
402402
exclude_patterns: Option<Vec<String>>,
403403
max_depth: Option<u32>,
404404
) -> Result<IndexResultDTO, String> {
405405
debug!("[WindAirCommands] IndexFiles called: {} with patterns: {:?}", path, patterns);
406406

407-
let air_address = get_air_address(&app_handle)?;
408-
let client = get_or_create_air_client(&app_handle, air_address).await?;
407+
let air_address = get_air_address(app_handle.inner())?;
408+
let client = get_or_create_air_client(app_handle.inner(), air_address).await?;
409409

410410
let request = IndexRequest {
411411
request_id: uuid::Uuid::new_v4().to_string(),
@@ -449,15 +449,15 @@ pub async fn IndexFiles(
449449
/// `SearchResultsDTO` with matching files
450450
#[tauri::command]
451451
pub async fn SearchFiles(
452-
app_handle: tauri::AppHandle,
452+
app_handle: tauri::State<'_, tauri::AppHandle>,
453453
query: String,
454454
index_id: Option<String>,
455455
max_results: Option<u32>,
456456
) -> Result<SearchResultsDTO, String> {
457457
debug!("[WindAirCommands] SearchFiles called: query={}, index={:?}", query, index_id);
458458

459-
let air_address = get_air_address(&app_handle)?;
460-
let client = get_or_create_air_client(&app_handle, air_address).await?;
459+
let air_address = get_air_address(app_handle.inner())?;
460+
let client = get_or_create_air_client(app_handle.inner(), air_address).await?;
461461

462462
let request = SearchRequest {
463463
request_id: uuid::Uuid::new_v4().to_string(),
@@ -506,12 +506,12 @@ pub async fn SearchFiles(
506506
/// `AirServiceStatusDTO` with service status information
507507
#[tauri::command]
508508
pub async fn GetAirStatus(
509-
app_handle: tauri::AppHandle,
509+
app_handle: tauri::State<'_, tauri::AppHandle>,
510510
) -> Result<AirServiceStatusDTO, String> {
511511
debug!("[WindAirCommands] GetAirStatus called");
512512

513-
let air_address = get_air_address(&app_handle)?;
514-
let client = get_or_create_air_client(&app_handle, air_address).await?;
513+
let air_address = get_air_address(app_handle.inner())?;
514+
let client = get_or_create_air_client(app_handle.inner(), air_address).await?;
515515

516516
let request = StatusRequest {
517517
request_id: uuid::Uuid::new_v4().to_string(),
@@ -553,13 +553,13 @@ pub async fn GetAirStatus(
553553
/// `AirMetricsDTO` with metrics data
554554
#[tauri::command]
555555
pub async fn GetAirMetrics(
556-
app_handle: tauri::AppHandle,
556+
app_handle: tauri::State<'_, tauri::AppHandle>,
557557
metric_type: Option<String>,
558558
) -> Result<AirMetricsDTO, String> {
559559
debug!("[WindAirCommands] GetAirMetrics called with type: {:?}", metric_type);
560560

561-
let air_address = get_air_address(&app_handle)?;
562-
let client = get_or_create_air_client(&app_handle, air_address).await?;
561+
let air_address = get_air_address(app_handle.inner())?;
562+
let client = get_or_create_air_client(app_handle.inner(), air_address).await?;
563563

564564
let request = MetricsRequest {
565565
request_id: uuid::Uuid::new_v4().to_string(),

Source/ProcessManagement/InitializationData.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::{collections::HashMap, env, sync::Arc};
1919
use Common::{
2020
Environment::Requires::Requires,
2121
Error::CommonError::CommonError,
22-
ExtensionManagement::ExtensionManagementService::ExtensionManagementService,
22+
ExtensionManagement::ExtensionManagementService,
2323
WorkSpace::WorkSpaceProvider::WorkSpaceProvider,
2424
};
2525
use log::info;
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
//! # CocoonServiceServer
2+
//!
3+
//! Implements the gRPC server for Mountain-Cocoon communication.
4+
5+
#![allow(non_snake_case, non_camel_case_types)]
6+
7+
use std::sync::Arc;
8+
use log::{debug, error, info};
9+
use tonic::{Request, Response, Status};
10+
use async_trait::async_trait;
11+
12+
use super::super::Generated::{
13+
cocoon_service_server::CocoonService,
14+
GenericRequest, GenericResponse, GenericNotification, CancelOperationRequest, Empty, RpcError
15+
};
16+
use crate::{
17+
ApplicationState::ApplicationState,
18+
Environment::MountainEnvironment::MountainEnvironment,
19+
};
20+
use Common::ExtensionManagement::ExtensionManagementService;
21+
22+
/// Implementation of the CocoonService gRPC server
23+
pub struct CocoonServiceImpl {
24+
/// Mountain environment
25+
environment: Arc<MountainEnvironment>,
26+
}
27+
28+
impl CocoonServiceImpl {
29+
/// Creates a new instance of the CocoonService server
30+
pub fn new(environment: Arc<MountainEnvironment>) -> Self {
31+
info!("[CocoonServiceImpl] New instance created");
32+
33+
Self {
34+
environment,
35+
}
36+
}
37+
38+
/// Handle generic Mountain requests from Cocoon
39+
async fn handle_mountain_request(
40+
&self,
41+
request: GenericRequest,
42+
) -> Result<GenericResponse, Status> {
43+
debug!(
44+
"[CocoonServiceImpl] Handling Mountain request '{}' with ID {}",
45+
request.method, request.request_identifier
46+
);
47+
48+
match request.method.as_str() {
49+
"InitializeExtensionHost" => {
50+
info!("[CocoonServiceImpl] Initializing extension host");
51+
52+
// Return success response
53+
Ok(GenericResponse {
54+
request_identifier: request.request_identifier,
55+
result: serde_json::to_vec(&"initialized").map_err(|e| {
56+
Status::internal(format!("Failed to serialize response: {}", e))
57+
})?,
58+
error: None,
59+
})
60+
}
61+
62+
"GetExtensions" => {
63+
debug!("[CocoonServiceServer] Getting extensions");
64+
65+
let extension_service: Arc<dyn ExtensionManagementService> = (*self.environment).Require();
66+
let extensions = extension_service.get_extensions().await.map_err(|e| {
67+
Status::internal(format!("Failed to get extensions: {}", e))
68+
})?;
69+
70+
Ok(GenericResponse {
71+
request_identifier: request.request_identifier,
72+
result: serde_json::to_vec(&extensions).map_err(|e| {
73+
Status::internal(format!("Failed to serialize extensions: {}", e))
74+
})?,
75+
error: None,
76+
})
77+
}
78+
79+
"ActivateExtension" => {
80+
debug!("[CocoonServiceServer] Activating extension");
81+
82+
let params: serde_json::Value = serde_json::from_slice(&request.parameter)
83+
.map_err(|e| Status::invalid_argument(format!("Invalid parameters: {}", e)))?;
84+
85+
let extension_id = params["extensionId"]
86+
.as_str()
87+
.ok_or_else(|| Status::invalid_argument("Missing extensionId parameter"))?;
88+
89+
let extension_service: Arc<dyn ExtensionManagementService> = (*self.environment).Require();
90+
extension_service.activate_extension(extension_id).await
91+
.map_err(|e| Status::internal(format!("Failed to activate extension: {}", e)))?;
92+
93+
Ok(GenericResponse {
94+
request_identifier: request.request_identifier,
95+
result: serde_json::to_vec(&"activated").map_err(|e| {
96+
Status::internal(format!("Failed to serialize response: {}", e))
97+
})?,
98+
error: None,
99+
})
100+
}
101+
102+
_ => {
103+
error!(
104+
"[CocoonServiceServer] Unknown Mountain request method '{}'",
105+
request.method
106+
);
107+
108+
Err(Status::unimplemented(format!(
109+
"Unknown method: {}",
110+
request.method
111+
)))
112+
}
113+
}
114+
}
115+
}
116+
117+
#[async_trait]
118+
impl CocoonService for CocoonServiceImpl {
119+
/// Process Mountain requests from Cocoon
120+
async fn process_mountain_request(
121+
&self,
122+
request: Request<GenericRequest>,
123+
) -> Result<Response<GenericResponse>, Status> {
124+
let request_data = request.into_inner();
125+
126+
match self.handle_mountain_request(request_data).await {
127+
Ok(response) => Ok(Response::new(response)),
128+
Err(status) => {
129+
error!("[CocoonServiceImpl] Error processing Mountain request: {}", status);
130+
Err(status)
131+
}
132+
}
133+
}
134+
135+
/// Send Mountain notifications to Cocoon
136+
async fn send_mountain_notification(
137+
&self,
138+
request: Request<GenericNotification>,
139+
) -> Result<Response<Empty>, Status> {
140+
let notification = request.into_inner();
141+
142+
debug!(
143+
"[CocoonServiceServer] Received Mountain notification '{}'",
144+
notification.method
145+
);
146+
147+
// Handle notifications (fire-and-forget)
148+
match notification.method.as_str() {
149+
"ExtensionActivated" => {
150+
info!("[CocoonServiceServer] Extension activated notification");
151+
}
152+
153+
"ExtensionDeactivated" => {
154+
info!("[CocoonServiceServer] Extension deactivated notification");
155+
}
156+
157+
_ => {
158+
debug!(
159+
"[CocoonServiceServer] Unknown Mountain notification '{}'",
160+
notification.method
161+
);
162+
}
163+
}
164+
165+
Ok(Response::new(Empty {}))
166+
}
167+
168+
/// Cancel operations requested by Mountain
169+
async fn cancel_operation(
170+
&self,
171+
request: Request<CancelOperationRequest>,
172+
) -> Result<Response<Empty>, Status> {
173+
let cancel_request = request.into_inner();
174+
175+
info!(
176+
"[CocoonServiceServer] Cancelling operation with ID {}",
177+
cancel_request.request_identifier_to_cancel
178+
);
179+
180+
// TODO: Implement operation cancellation logic
181+
182+
Ok(Response::new(Empty {}))
183+
}
184+
}

0 commit comments

Comments
 (0)