uv_platform/
os.rs

1use crate::Error;
2use std::fmt;
3use std::fmt::Display;
4use std::ops::Deref;
5use std::str::FromStr;
6
7#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
8pub struct Os(pub(crate) target_lexicon::OperatingSystem);
9
10impl Os {
11    pub fn new(os: target_lexicon::OperatingSystem) -> Self {
12        Self(os)
13    }
14
15    pub fn from_env() -> Self {
16        Self(target_lexicon::HOST.operating_system)
17    }
18
19    pub fn is_windows(&self) -> bool {
20        matches!(self.0, target_lexicon::OperatingSystem::Windows)
21    }
22
23    pub fn is_emscripten(&self) -> bool {
24        matches!(self.0, target_lexicon::OperatingSystem::Emscripten)
25    }
26
27    pub fn is_macos(&self) -> bool {
28        matches!(self.0, target_lexicon::OperatingSystem::Darwin(_))
29    }
30
31    /// Whether this OS can run the other OS.
32    pub fn supports(&self, other: Self) -> bool {
33        // Emscripten cannot run on Windows, but all other OSes can run Emscripten.
34        if other.is_emscripten() {
35            return !self.is_windows();
36        }
37        if self.is_windows() && other.is_emscripten() {
38            return false;
39        }
40
41        // Otherwise, we require an exact match
42        *self == other
43    }
44}
45
46impl Display for Os {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        match &**self {
49            target_lexicon::OperatingSystem::Darwin(_) => write!(f, "macos"),
50            inner => write!(f, "{inner}"),
51        }
52    }
53}
54
55impl FromStr for Os {
56    type Err = Error;
57
58    fn from_str(s: &str) -> Result<Self, Self::Err> {
59        let inner = match s {
60            "macos" => target_lexicon::OperatingSystem::Darwin(None),
61            _ => target_lexicon::OperatingSystem::from_str(s)
62                .map_err(|()| Error::UnknownOs(s.to_string()))?,
63        };
64        if matches!(inner, target_lexicon::OperatingSystem::Unknown) {
65            return Err(Error::UnknownOs(s.to_string()));
66        }
67        Ok(Self(inner))
68    }
69}
70
71impl Deref for Os {
72    type Target = target_lexicon::OperatingSystem;
73
74    fn deref(&self) -> &Self::Target {
75        &self.0
76    }
77}
78
79impl From<&uv_platform_tags::Os> for Os {
80    fn from(value: &uv_platform_tags::Os) -> Self {
81        match value {
82            uv_platform_tags::Os::Dragonfly { .. } => {
83                Self::new(target_lexicon::OperatingSystem::Dragonfly)
84            }
85            uv_platform_tags::Os::FreeBsd { .. } => {
86                Self::new(target_lexicon::OperatingSystem::Freebsd)
87            }
88            uv_platform_tags::Os::Haiku { .. } => Self::new(target_lexicon::OperatingSystem::Haiku),
89            uv_platform_tags::Os::Illumos { .. } => {
90                Self::new(target_lexicon::OperatingSystem::Illumos)
91            }
92            uv_platform_tags::Os::Macos { .. } => {
93                Self::new(target_lexicon::OperatingSystem::Darwin(None))
94            }
95            uv_platform_tags::Os::Manylinux { .. }
96            | uv_platform_tags::Os::Musllinux { .. }
97            | uv_platform_tags::Os::Android { .. } => {
98                Self::new(target_lexicon::OperatingSystem::Linux)
99            }
100            uv_platform_tags::Os::NetBsd { .. } => {
101                Self::new(target_lexicon::OperatingSystem::Netbsd)
102            }
103            uv_platform_tags::Os::OpenBsd { .. } => {
104                Self::new(target_lexicon::OperatingSystem::Openbsd)
105            }
106            uv_platform_tags::Os::Windows => Self::new(target_lexicon::OperatingSystem::Windows),
107            uv_platform_tags::Os::Pyodide { .. } => {
108                Self::new(target_lexicon::OperatingSystem::Emscripten)
109            }
110            uv_platform_tags::Os::Ios { .. } => {
111                Self::new(target_lexicon::OperatingSystem::IOS(None))
112            }
113        }
114    }
115}