system_specs.rs

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