panda/api/
os.rs

1use crate::sys::{
2    panda_os_bits, panda_os_family, panda_os_familyno, panda_os_name, panda_os_variant,
3};
4use once_cell::sync::Lazy;
5
6use std::ffi::CStr;
7
8macro_rules! convert_static_str {
9    ($str_name:ident) => {
10        if unsafe { $str_name.is_null() } {
11            None
12        } else {
13            let c_string = unsafe { CStr::from_ptr($str_name) };
14
15            Some(c_string.to_string_lossy().into_owned())
16        }
17    };
18}
19
20/// Get the name of the OS currently set. This is typically set by the `-os` command line
21/// argument passed to a PANDA instance.
22pub static NAME: Lazy<Option<String>> = Lazy::new(|| unsafe {
23    if panda_os_name.is_null() {
24        None
25    } else {
26        CStr::from_ptr(panda_os_name)
27            .to_str()
28            .ok()
29            .map(String::from)
30    }
31});
32
33/// Get the name of the OS currently set. This is typically set by the `-os` command line
34/// argument passed to a PANDA instance.
35pub fn name() -> Option<String> {
36    convert_static_str!(panda_os_name)
37}
38
39/// Get the family name of the OS currently set. This is typically set by the `-os`
40/// command line argument passed to a PANDA instance.
41pub fn family_name() -> Option<String> {
42    convert_static_str!(panda_os_family)
43}
44
45/// Get the name of the variation of the OS currently set. This is typically set by the
46/// `-os` command line argument passed to a PANDA instance.
47pub fn variant() -> Option<String> {
48    convert_static_str!(panda_os_variant)
49}
50
51/// The bit-width of the OS being currently run. This is not necessarily equivelant to the
52/// bit-width of the architecture as, for example, 32-bit Windows can run on a 64-bit
53/// x86 processor.
54///
55/// This is typically set by the `-os` command line argument passed to a PANDA instance.
56pub fn bits() -> u32 {
57    unsafe { panda_os_bits }
58}
59
60#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
61#[repr(u32)]
62pub enum OsFamily {
63    Unknown = 0,
64    Windows = 1,
65    Linux = 2,
66    FreeBsd = 3,
67}
68
69impl OsFamily {
70    pub fn is_linux(self) -> bool {
71        self == OsFamily::Linux
72    }
73
74    pub fn is_windows(self) -> bool {
75        self == OsFamily::Windows
76    }
77
78    pub fn is_bsd(self) -> bool {
79        self == OsFamily::FreeBsd
80    }
81
82    pub fn is_unix(self) -> bool {
83        self.is_linux() | self.is_bsd()
84    }
85}
86
87impl From<u32> for OsFamily {
88    fn from(fam: u32) -> Self {
89        match fam {
90            1 => OsFamily::Windows,
91            2 => OsFamily::Linux,
92            3 => OsFamily::FreeBsd,
93            _ => OsFamily::Unknown,
94        }
95    }
96}
97
98/// The family of OS being run (Windows, Linux, etc).
99///
100/// This is typically set by the `-os` command line argument passed to a PANDA instance.
101pub fn family() -> OsFamily {
102    OsFamily::from(unsafe { panda_os_familyno })
103}