system_specs.rs

 1use client::telemetry;
 2use gpui::Task;
 3use human_bytes::human_bytes;
 4use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
 5use serde::Serialize;
 6use std::{env, fmt::Display};
 7use sysinfo::{MemoryRefreshKind, RefreshKind, System};
 8use ui::WindowContext;
 9
10#[derive(Clone, Debug, Serialize)]
11pub struct SystemSpecs {
12    app_version: String,
13    release_channel: &'static str,
14    os_name: String,
15    os_version: String,
16    memory: u64,
17    architecture: &'static str,
18    commit_sha: Option<String>,
19    gpu_specs: Option<String>,
20}
21
22impl SystemSpecs {
23    pub fn new(cx: &WindowContext) -> Task<Self> {
24        let app_version = AppVersion::global(cx).to_string();
25        let release_channel = ReleaseChannel::global(cx);
26        let os_name = telemetry::os_name();
27        let system = System::new_with_specifics(
28            RefreshKind::new().with_memory(MemoryRefreshKind::everything()),
29        );
30        let memory = system.total_memory();
31        let architecture = env::consts::ARCH;
32        let commit_sha = match release_channel {
33            ReleaseChannel::Dev | ReleaseChannel::Nightly => {
34                AppCommitSha::try_global(cx).map(|sha| sha.0.clone())
35            }
36            _ => None,
37        };
38
39        let gpu_specs = if let Some(specs) = cx.gpu_specs() {
40            Some(format!(
41                "{} || {} || {}",
42                specs.device_name, specs.driver_name, specs.driver_info
43            ))
44        } else {
45            None
46        };
47
48        cx.background_executor().spawn(async move {
49            let os_version = telemetry::os_version();
50            SystemSpecs {
51                app_version,
52                release_channel: release_channel.display_name(),
53                os_name,
54                os_version,
55                memory,
56                architecture,
57                commit_sha,
58                gpu_specs,
59            }
60        })
61    }
62}
63
64impl Display for SystemSpecs {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        let os_information = format!("OS: {} {}", self.os_name, self.os_version);
67        let app_version_information = format!(
68            "Zed: v{} ({})",
69            self.app_version,
70            match &self.commit_sha {
71                Some(commit_sha) => format!("{} {}", self.release_channel, commit_sha),
72                None => self.release_channel.to_string(),
73            }
74        );
75        let system_specs = [
76            app_version_information,
77            os_information,
78            format!("Memory: {}", human_bytes(self.memory as f64)),
79            format!("Architecture: {}", self.architecture),
80        ]
81        .into_iter()
82        .chain(
83            self.gpu_specs
84                .as_ref()
85                .map(|specs| format!("GPU: {}", specs)),
86        )
87        .collect::<Vec<String>>()
88        .join("\n");
89
90        write!(f, "{system_specs}")
91    }
92}