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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// TODO: no_std

extern crate cpuid;
#[macro_use]
extern crate quick_error;
extern crate semver;

#[cfg(unix)]
mod unix;

#[cfg(unix)]
use unix::{PlatformError, total_memory};
#[cfg(unix)]
pub use unix::os;

#[cfg(windows)]
mod windows;

#[cfg(windows)]
use windows::{PlatformError, total_memory};
#[cfg(windows)]
pub use windows::os;

use semver::{SemVerError, Version};
use std::{io, result};
use std::error::Error as ErrorTrait;

/// Information about the current operating system
pub struct OSVersion {
    /// Full name of the operating system
    pub name: String,
    // TODO: os_type
    /// OS version info
    pub version: Version,

    #[cfg(unix)]
    /// Distribution name
    pub distribution: String,

    #[cfg(windows)]
    /// Service pack version
    pub service_pack_version: Version,
}

/// Basic hardware information
pub struct Platform {
    // TODO: NUMA?
    /// CPU name
    pub cpu: String,
    /// CPU vendor
    pub cpu_vendor: String,

    /// Total installed memory
    pub memory: u64,
}

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        PlatformError(err: PlatformError) {
            from()
            description(err.description())
            display("{}", err)
        }

        IO(err: io::Error) {
            from()
            description(err.description())
            display(s) -> ("{}: {}", s.description(), err)
        }

        SemVer(err: SemVerError) {
            from()
            description(err.description())
            display(s) -> ("{}: {}", s.description(), err)
        }

        String(err: String) {
            from()
            description(err)
            display("{}", err)
        }
    }
}

pub type Result<T> = result::Result<T, Error>;

/// Get basic information about the hardware we're running on.
///
/// # Requirements
///
/// For *nix: a functional `/proc` filesystem with system information. For
/// Windows: XP or Server 2003.
// TODO: don't show requirements for anothe system in the doc
pub fn platform() -> Result<Platform> {
    let cpu = cpuid::identify()?;

    Ok(Platform {
        cpu: cpu.brand,
        cpu_vendor: cpu.vendor,

        memory: total_memory(),
    })
}