Skip to main content

Mountain/Vine/Server/Notification/
TerminalLifecycle.rs

1//! Cocoon → Mountain `terminal.sendText` / `terminal.show` / `terminal.hide` /
2//! `terminal.dispose` notifications. Shared atom because the four wire
3//! methods all fan through the same `sky://terminal/*` relay and the
4//! same provider-side PTY drive, differing only in which provider call
5//! fires (sendText vs dispose) and whether the payload carries text.
6//!
7//! Two concerns per invocation:
8//!   1. Notify Sky on `sky://terminal/<suffix>` so the xterm panel can
9//!      show/hide / print text / remove the panel.
10//!   2. Drive the underlying PTY via the `TerminalProvider` so the OS process
11//!      sees the text / receives SIGHUP on dispose.
12
13use std::sync::Arc;
14
15use serde_json::Value;
16use tauri::Emitter;
17use CommonLibrary::{Environment::Requires::Requires, Terminal::TerminalProvider::TerminalProvider};
18
19use crate::{Vine::Server::MountainVinegRPCService::MountainVinegRPCService, dev_log};
20
21pub async fn TerminalLifecycle(Service:&MountainVinegRPCService, MethodName:&str, Parameter:&Value) {
22	let EventName = format!("sky://terminal/{}", &MethodName["terminal.".len()..]);
23
24	if let Err(Error) = Service.ApplicationHandle().emit(&EventName, Parameter) {
25		dev_log!("grpc", "warn: [MountainVinegRPCService] {} emit failed: {}", EventName, Error);
26	}
27
28	// Terminal handles from Cocoon arrive as `terminal:N`; strip the
29	// prefix to recover the numeric identifier the provider expects.
30	let HandleNumeric = Parameter
31		.get("handle")
32		.and_then(|H| H.as_str())
33		.and_then(|S| S.trim_start_matches("terminal:").parse::<u64>().ok());
34
35	if let Some(TerminalId) = HandleNumeric {
36		let Provider:Arc<dyn TerminalProvider> = Service.RunTime().Environment.Require();
37
38		match MethodName {
39			"terminal.sendText" => {
40				let Text = Parameter.get("text").and_then(|T| T.as_str()).unwrap_or("").to_string();
41
42				let ProviderForTask = Provider.clone();
43
44				tokio::spawn(async move {
45					let _ = ProviderForTask.SendTextToTerminal(TerminalId, Text).await;
46				});
47			},
48
49			"terminal.dispose" => {
50				let ProviderForTask = Provider.clone();
51
52				tokio::spawn(async move {
53					let _ = ProviderForTask.DisposeTerminal(TerminalId).await;
54				});
55			},
56
57			_ => {},
58		}
59	}
60}