Skip to main content

dolang_vfs/
target.rs

1//! Target-platform descriptions and capabilities.
2
3use serde::{Deserialize, Serialize};
4
5/// Operating system that produced a target description or native error code.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[non_exhaustive]
8pub enum OperatingSystem {
9    /// FreeBSD.
10    FreeBsd,
11    /// Linux.
12    Linux,
13    /// macOS.
14    Macos,
15    /// Windows.
16    Windows,
17}
18
19impl OperatingSystem {
20    /// Returns the operating system of the current host.
21    pub fn current() -> Self {
22        #[cfg(target_os = "linux")]
23        return Self::Linux;
24        #[cfg(target_os = "macos")]
25        return Self::Macos;
26        #[cfg(target_os = "freebsd")]
27        return Self::FreeBsd;
28        #[cfg(windows)]
29        return Self::Windows;
30        #[cfg(not(any(
31            target_os = "linux",
32            target_os = "macos",
33            target_os = "freebsd",
34            windows
35        )))]
36        compile_error!("unsupported target operating system");
37    }
38
39    /// Returns the path syntax associated with this operating system.
40    pub const fn path_kind(&self) -> crate::path::Kind {
41        match self {
42            Self::Linux | Self::Macos | Self::FreeBsd => crate::path::Kind::Unix,
43            Self::Windows => crate::path::Kind::Windows,
44        }
45    }
46}
47
48/// CPU architecture reported by a VFS target.
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
50#[non_exhaustive]
51pub enum Architecture {
52    /// 64-bit x86.
53    X86_64,
54    /// 64-bit ARM.
55    Aarch64,
56}
57
58/// Broad operating-system family used for platform-specific behavior.
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum OperatingSystemFamily {
61    /// Unix-like operating systems.
62    Unix,
63    /// Windows operating systems.
64    Windows,
65}
66
67/// Target operating-system and processor information.
68#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
69pub struct TargetInfo {
70    /// Target operating system.
71    pub(crate) os: OperatingSystem,
72    /// Target CPU architecture.
73    pub(crate) arch: Architecture,
74    /// Number of logical CPUs available to the target.
75    pub(crate) logical_cpus: u32,
76    /// Whether the target is Windows running under Wine, when applicable.
77    pub(crate) is_wine: Option<bool>,
78}
79
80impl Architecture {
81    /// Returns the architecture of the current host.
82    pub fn current() -> Self {
83        #[cfg(target_arch = "x86_64")]
84        return Self::X86_64;
85        #[cfg(target_arch = "aarch64")]
86        return Self::Aarch64;
87        #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
88        compile_error!("unsupported target architecture");
89    }
90}
91
92impl OperatingSystem {
93    /// Returns the broad family containing this operating system.
94    pub fn family(&self) -> OperatingSystemFamily {
95        match self {
96            Self::FreeBsd | Self::Linux | Self::Macos => OperatingSystemFamily::Unix,
97            Self::Windows => OperatingSystemFamily::Windows,
98        }
99    }
100}
101
102impl TargetInfo {
103    /// Returns the target operating system.
104    pub const fn os(&self) -> OperatingSystem {
105        self.os
106    }
107    /// Returns the target CPU architecture.
108    pub const fn arch(&self) -> Architecture {
109        self.arch
110    }
111    /// Returns the number of logical CPUs available to the target.
112    pub const fn logical_cpus(&self) -> u32 {
113        self.logical_cpus
114    }
115    /// Returns whether Windows is running under Wine, when applicable.
116    pub const fn is_wine(&self) -> Option<bool> {
117        self.is_wine
118    }
119    /// Returns a description of the current host.
120    pub fn current() -> Self {
121        Self {
122            os: OperatingSystem::current(),
123            arch: Architecture::current(),
124            logical_cpus: std::thread::available_parallelism()
125                .map_or(1, |count| u32::try_from(count.get()).unwrap_or(u32::MAX)),
126            is_wine: current_wine_status(),
127        }
128    }
129}
130
131#[cfg(windows)]
132fn current_wine_status() -> Option<bool> {
133    Some(dolang_winterop::is_wine())
134}
135
136#[cfg(not(windows))]
137fn current_wine_status() -> Option<bool> {
138    None
139}