Skip to main content

Mountain/IPC/WindServiceHandler/
Environment.rs

1#![allow(non_snake_case)]
2
3//! Environment domain handlers for Wind IPC.
4
5use std::sync::Arc;
6
7use serde_json::{Value, json};
8
9use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
10
11/// Handler for environment get requests
12pub async fn handle_environment_get(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
13	let Key = Args
14		.get(0)
15		.ok_or("Missing environment key".to_string())?
16		.as_str()
17		.ok_or("Environment key must be a string".to_string())?;
18
19	let EnvValue = std::env::var(Key).map_err(|E| format!("Failed to get environment variable: {}", E))?;
20
21	dev_log!("config", "env_get: {}", Key);
22	Ok(json!(EnvValue))
23}
24
25/// Handler for showing items in folder
26pub async fn handle_show_item_in_folder(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
27	let PathStr = Args
28		.get(0)
29		.ok_or("Missing file path".to_string())?
30		.as_str()
31		.ok_or("File path must be a string".to_string())?;
32
33	dev_log!("vfs", "showInFolder: {}", PathStr);
34
35	let Path = std::path::PathBuf::from(PathStr);
36
37	if !Path.exists() {
38		return Err(format!("Path does not exist: {}", PathStr));
39	}
40
41	#[cfg(target_os = "macos")]
42	{
43		use std::process::Command;
44
45		let Result = Command::new("open")
46			.arg("-R")
47			.arg(&Path)
48			.output()
49			.map_err(|E| format!("Failed to execute open command: {}", E))?;
50
51		if !Result.status.success() {
52			return Err(format!(
53				"Failed to show item in folder: {}",
54				String::from_utf8_lossy(&Result.stderr)
55			));
56		}
57	}
58
59	#[cfg(target_os = "windows")]
60	{
61		use std::process::Command;
62
63		let Result = Command::new("explorer")
64			.arg("/select,")
65			.arg(&Path)
66			.output()
67			.map_err(|E| format!("Failed to execute explorer command: {}", E))?;
68
69		if !Result.status.success() {
70			return Err(format!(
71				"Failed to show item in folder: {}",
72				String::from_utf8_lossy(&Result.stderr)
73			));
74		}
75	}
76
77	#[cfg(target_os = "linux")]
78	{
79		use std::process::Command;
80
81		let FileManagers = ["nautilus", "dolphin", "thunar", "pcmanfm", "nemo"];
82		let mut LastError = String::new();
83
84		for Manager in FileManagers.iter() {
85			let Result = Command::new(Manager).arg(&Path).output();
86
87			match Result {
88				Ok(Output) if Output.status.success() => {
89					dev_log!("lifecycle", "opened with {}", Manager);
90					break;
91				},
92				Err(E) => {
93					LastError = E.to_string();
94					continue;
95				},
96				_ => continue,
97			}
98		}
99
100		if !LastError.is_empty() {
101			return Err(format!("Failed to show item in folder with any file manager: {}", LastError));
102		}
103	}
104
105	dev_log!("vfs", "showed in folder: {}", PathStr);
106	Ok(Value::Bool(true))
107}
108
109/// Handler for opening external URLs
110pub async fn handle_open_external(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
111	let UrlStr = Args
112		.get(0)
113		.ok_or("Missing URL".to_string())?
114		.as_str()
115		.ok_or("URL must be a string".to_string())?;
116
117	dev_log!("lifecycle", "openExternal: {}", UrlStr);
118
119	if !UrlStr.starts_with("http://") && !UrlStr.starts_with("https://") {
120		return Err(format!("Invalid URL format. Must start with http:// or https://: {}", UrlStr));
121	}
122
123	#[cfg(target_os = "macos")]
124	{
125		use std::process::Command;
126
127		let Result = Command::new("open")
128			.arg(UrlStr)
129			.output()
130			.map_err(|E| format!("Failed to execute open command: {}", E))?;
131
132		if !Result.status.success() {
133			return Err(format!("Failed to open URL: {}", String::from_utf8_lossy(&Result.stderr)));
134		}
135	}
136
137	#[cfg(target_os = "windows")]
138	{
139		use std::process::Command;
140
141		let Result = Command::new("cmd")
142			.arg("/c")
143			.arg("start")
144			.arg(UrlStr)
145			.output()
146			.map_err(|E| format!("Failed to execute start command: {}", E))?;
147
148		if !Result.status.success() {
149			return Err(format!("Failed to open URL: {}", String::from_utf8_lossy(&Result.stderr)));
150		}
151	}
152
153	#[cfg(target_os = "linux")]
154	{
155		use std::process::Command;
156
157		let Handlers = ["xdg-open", "gnome-open", "kde-open", "x-www-browser"];
158		let mut LastError = String::new();
159
160		for Handler in Handlers.iter() {
161			let Result = Command::new(Handler).arg(UrlStr).output();
162
163			match Result {
164				Ok(Output) if Output.status.success() => {
165					dev_log!("lifecycle", "opened with {}", Handler);
166					break;
167				},
168				Err(E) => {
169					LastError = E.to_string();
170					continue;
171				},
172				_ => continue,
173			}
174		}
175
176		if !LastError.is_empty() {
177			return Err(format!("Failed to open URL with any handler: {}", LastError));
178		}
179	}
180
181	dev_log!("lifecycle", "opened URL: {}", UrlStr);
182	Ok(Value::Bool(true))
183}