Skip to main content

Mountain/IPC/WindServiceHandlers/NativeHost/
OSProperties.rs

1//! Wire method: `nativeHost:getOSProperties` (cross-platform).
2//! Returns Electron-shaped `{ type, release, arch, platform, cpus }` tuple.
3//! Cached for the process lifetime - OS type, version, arch, and CPU topology
4//! are stable; spawning `sw_vers`/`uname` on every call wastes ~10 ms each.
5
6use std::sync::OnceLock;
7
8use serde_json::{Value, json};
9
10static OS_PROPERTIES_CACHE:OnceLock<Value> = OnceLock::new();
11
12pub async fn Fn() -> Result<Value, String> {
13	if let Some(Cached) = OS_PROPERTIES_CACHE.get() {
14		return Ok(Cached.clone());
15	}
16
17	let Result = compute_os_properties();
18
19	let _ = OS_PROPERTIES_CACHE.set(Result.clone());
20
21	Ok(Result)
22}
23
24fn compute_os_properties() -> Value {
25	use sysinfo::System;
26
27	let OsType = match std::env::consts::OS {
28		"macos" => "Darwin",
29
30		"windows" => "Windows_NT",
31
32		"linux" => "Linux",
33
34		_ => std::env::consts::OS,
35	};
36
37	let Release = {
38		#[cfg(target_os = "macos")]
39		{
40			std::process::Command::new("sw_vers")
41				.arg("-productVersion")
42				.output()
43				.ok()
44				.map(|O| String::from_utf8_lossy(&O.stdout).trim().to_string())
45				.unwrap_or_else(|| "14.0".to_string())
46		}
47
48		#[cfg(target_os = "windows")]
49		{
50			std::process::Command::new("cmd")
51				.args(["/c", "ver"])
52				.output()
53				.ok()
54				.map(|O| {
55					let Output = String::from_utf8_lossy(&O.stdout);
56
57					Output
58						.split('[')
59						.nth(1)
60						.and_then(|S| S.split(']').next())
61						.and_then(|S| S.strip_prefix("Version "))
62						.unwrap_or("10.0.0")
63						.to_string()
64				})
65				.unwrap_or_else(|| "10.0.0".to_string())
66		}
67
68		#[cfg(target_os = "linux")]
69		{
70			std::process::Command::new("uname")
71				.arg("-r")
72				.output()
73				.ok()
74				.map(|O| String::from_utf8_lossy(&O.stdout).trim().to_string())
75				.unwrap_or_else(|| "6.1.0".to_string())
76		}
77
78		#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
79		{
80			"0.0.0".to_string()
81		}
82	};
83
84	let mut Sys = System::new();
85
86	Sys.refresh_cpu_all();
87
88	let Cpus:Vec<Value> = Sys
89		.cpus()
90		.iter()
91		.map(|Cpu| {
92			json!({
93				"model": Cpu.brand(),
94				"speed": Cpu.frequency()
95			})
96		})
97		.collect();
98
99	json!({
100		"type": OsType,
101		"release": Release,
102		"arch": std::env::consts::ARCH,
103		"platform": std::env::consts::OS,
104		"cpus": Cpus
105	})
106}