1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::fmt::{Debug, Formatter};
use sysinfo::{CpuExt, SystemExt};

#[derive(Clone)]
pub struct SystemInfo {
    system: String,
    cpu_brand: String,
    cpu_cores: usize,
    memory_total: u64,
    memory_available: u64,
    pub(crate) renderer: String,
    pub(crate) hw_acceleration: String,
}

impl SystemInfo {
    pub fn new() -> Self {
        let mut sys = sysinfo::System::new_all();
        sys.refresh_memory();
        sys.refresh_cpu();

        Self {
            system: format!(
                "{} ({}) ({})",
                sys.name().unwrap_or_else(|| "".to_owned()).trim(),
                sys.long_os_version()
                    .unwrap_or_else(|| "?".to_owned())
                    .trim(),
                sys.kernel_version()
                    .unwrap_or_else(|| "?".to_owned())
                    .trim(),
            ),
            cpu_brand: sys.global_cpu_info().brand().to_string(),
            cpu_cores: sys.cpus().len(),
            memory_total: sys.total_memory(),
            memory_available: sys.available_memory(),
            renderer: "(?)".to_owned(),
            hw_acceleration: "(?)".to_owned(),
        }
    }
}

impl Default for SystemInfo {
    fn default() -> Self {
        Self::new()
    }
}

impl Debug for SystemInfo {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "System: {}\nCPU: {} (x{})\nMemory (GiB): {:.1} (available: {:.1})\n\
            Renderer: {}\nHW acceleration: {}",
            self.system,
            self.cpu_brand,
            self.cpu_cores,
            self.memory_total as f64 / 2_f64.powi(30),
            self.memory_available as f64 / 2_f64.powi(30),
            self.renderer,
            self.hw_acceleration
        )
    }
}