system_specs.rs

 1use client::ZED_APP_VERSION;
 2use gpui::{platform::AppVersion, AppContext};
 3use human_bytes::human_bytes;
 4use serde::Serialize;
 5use std::{env, fmt::Display};
 6use sysinfo::{System, SystemExt};
 7use util::channel::ReleaseChannel;
 8
 9#[derive(Clone, Debug, Serialize)]
10pub struct SystemSpecs {
11    #[serde(serialize_with = "serialize_app_version")]
12    app_version: Option<AppVersion>,
13    release_channel: &'static str,
14    os_name: &'static str,
15    os_version: Option<String>,
16    memory: u64,
17    architecture: &'static str,
18}
19
20impl SystemSpecs {
21    pub fn new(cx: &AppContext) -> Self {
22        let platform = cx.platform();
23        let app_version = ZED_APP_VERSION.or_else(|| platform.app_version().ok());
24        let release_channel = cx.global::<ReleaseChannel>().dev_name();
25        let os_name = platform.os_name();
26        let system = System::new_all();
27        let memory = system.total_memory();
28        let architecture = env::consts::ARCH;
29        let os_version = platform
30            .os_version()
31            .ok()
32            .map(|os_version| os_version.to_string());
33
34        SystemSpecs {
35            app_version,
36            release_channel,
37            os_name,
38            os_version,
39            memory,
40            architecture,
41        }
42    }
43}
44
45impl Display for SystemSpecs {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        let os_information = match &self.os_version {
48            Some(os_version) => format!("OS: {} {}", self.os_name, os_version),
49            None => format!("OS: {}", self.os_name),
50        };
51        let app_version_information = self
52            .app_version
53            .as_ref()
54            .map(|app_version| format!("Zed: v{} ({})", app_version, self.release_channel));
55        let system_specs = [
56            app_version_information,
57            Some(os_information),
58            Some(format!("Memory: {}", human_bytes(self.memory as f64))),
59            Some(format!("Architecture: {}", self.architecture)),
60        ]
61        .into_iter()
62        .flatten()
63        .collect::<Vec<String>>()
64        .join("\n");
65
66        write!(f, "{system_specs}")
67    }
68}
69
70fn serialize_app_version<S>(version: &Option<AppVersion>, serializer: S) -> Result<S::Ok, S::Error>
71where
72    S: serde::Serializer,
73{
74    version.map(|v| v.to_string()).serialize(serializer)
75}