Skip to main content

Mountain/Vine/Server/Notification/
TerminalLifecycle.rs

1#![allow(non_snake_case)]
2//! Cocoon → Mountain `terminal.sendText` / `terminal.show` / `terminal.hide` /
3//! `terminal.dispose` notifications. Shared atom because the four wire
4//! methods all fan through the same `sky://terminal/*` relay and the
5//! same provider-side PTY drive, differing only in which provider call
6//! fires (sendText vs dispose) and whether the payload carries text.
7//!
8//! Two concerns per invocation:
9//!   1. Notify Sky on `sky://terminal/<suffix>` so the xterm panel can
10//!      show/hide / print text / remove the panel.
11//!   2. Drive the underlying PTY via the `TerminalProvider` so the OS process
12//!      sees the text / receives SIGHUP on dispose.
13
14use std::sync::Arc;
15
16use serde_json::Value;
17use tauri::Emitter;
18use CommonLibrary::{Environment::Requires::Requires, Terminal::TerminalProvider::TerminalProvider};
19
20use crate::{Vine::Server::MountainVinegRPCService::MountainVinegRPCService, dev_log};
21
22pub async fn TerminalLifecycle(Service:&MountainVinegRPCService, MethodName:&str, Parameter:&Value) {
23	let EventName = format!("sky://terminal/{}", &MethodName["terminal.".len()..]);
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	if let Some(TerminalId) = HandleNumeric {
35		let Provider:Arc<dyn TerminalProvider> = Service.RunTime().Environment.Require();
36		match MethodName {
37			"terminal.sendText" => {
38				let Text = Parameter.get("text").and_then(|T| T.as_str()).unwrap_or("").to_string();
39				let ProviderForTask = Provider.clone();
40				tokio::spawn(async move {
41					let _ = ProviderForTask.SendTextToTerminal(TerminalId, Text).await;
42				});
43			},
44			"terminal.dispose" => {
45				let ProviderForTask = Provider.clone();
46				tokio::spawn(async move {
47					let _ = ProviderForTask.DisposeTerminal(TerminalId).await;
48				});
49			},
50			_ => {},
51		}
52	}
53}