1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[non_exhaustive]
8pub enum OperatingSystem {
9 FreeBsd,
11 Linux,
13 Macos,
15 Windows,
17}
18
19impl OperatingSystem {
20 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 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#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
50#[non_exhaustive]
51pub enum Architecture {
52 X86_64,
54 Aarch64,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum OperatingSystemFamily {
61 Unix,
63 Windows,
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
69pub struct TargetInfo {
70 pub(crate) os: OperatingSystem,
72 pub(crate) arch: Architecture,
74 pub(crate) logical_cpus: u32,
76 pub(crate) is_wine: Option<bool>,
78}
79
80impl Architecture {
81 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 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 pub const fn os(&self) -> OperatingSystem {
105 self.os
106 }
107 pub const fn arch(&self) -> Architecture {
109 self.arch
110 }
111 pub const fn logical_cpus(&self) -> u32 {
113 self.logical_cpus
114 }
115 pub const fn is_wine(&self) -> Option<bool> {
117 self.is_wine
118 }
119 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}