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