Skip to main content

node_js_release_info/
os.rs

1use crate::error::NodeJsRelInfoError;
2#[cfg(feature = "json")]
3use serde::{Deserialize, Serialize};
4use std::env::consts::OS;
5use std::fmt::{Display, Formatter};
6use std::str::FromStr;
7
8/// The operating system a Node.js distributable targets
9///
10/// Non-exhaustive: Node.js has added and removed target platforms over time,
11/// so new variants may appear in a minor release
12#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
13#[cfg_attr(feature = "json", derive(Deserialize, Serialize))]
14#[non_exhaustive]
15pub enum NodeJsOs {
16    /// Linux (`linux`)
17    #[default]
18    #[cfg_attr(feature = "json", serde(rename = "linux"))]
19    Linux,
20    /// macOS (`darwin`)
21    #[cfg_attr(feature = "json", serde(rename = "darwin"))]
22    Darwin,
23    /// Windows (`win`)
24    #[cfg_attr(feature = "json", serde(rename = "win"))]
25    Windows,
26    /// IBM AIX (`aix`)
27    #[cfg_attr(feature = "json", serde(rename = "aix"))]
28    Aix,
29    /// illumos / Solaris (`sunos`) - shipped up to Node.js v14
30    #[cfg_attr(feature = "json", serde(rename = "sunos"))]
31    SunOs,
32}
33
34impl NodeJsOs {
35    /// Creates a new instance using the default OS ([`Linux`](NodeJsOs::Linux))
36    ///
37    /// # Examples
38    ///
39    /// ```rust
40    /// use node_js_release_info::NodeJsOs;
41    /// assert_eq!(NodeJsOs::new(), NodeJsOs::Linux);
42    /// ```
43    pub fn new() -> NodeJsOs {
44        NodeJsOs::default()
45    }
46
47    /// Determines the OS of the current environment via
48    /// [`std::env::consts::OS`]
49    ///
50    /// # Errors
51    ///
52    /// Returns [`NodeJsRelInfoError::UnrecognizedOs`] when the current OS has
53    /// no corresponding Node.js distributable
54    pub fn from_env() -> Result<NodeJsOs, NodeJsRelInfoError> {
55        NodeJsOs::from_str(OS)
56    }
57}
58
59impl Display for NodeJsOs {
60    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
61        let os = match self {
62            NodeJsOs::Linux => "linux",
63            NodeJsOs::Darwin => "darwin",
64            NodeJsOs::Windows => "win",
65            NodeJsOs::Aix => "aix",
66            NodeJsOs::SunOs => "sunos",
67        };
68
69        write!(f, "{os}")
70    }
71}
72
73impl FromStr for NodeJsOs {
74    type Err = NodeJsRelInfoError;
75
76    fn from_str(s: &str) -> Result<NodeJsOs, NodeJsRelInfoError> {
77        match s {
78            "linux" => Ok(NodeJsOs::Linux),
79            "darwin" | "macos" => Ok(NodeJsOs::Darwin),
80            "windows" | "win" => Ok(NodeJsOs::Windows),
81            "sunos" | "solaris" | "illumos" => Ok(NodeJsOs::SunOs),
82            "aix" => Ok(NodeJsOs::Aix),
83            _ => Err(NodeJsRelInfoError::UnrecognizedOs(s.to_string())),
84        }
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn it_initializes() {
94        let os = NodeJsOs::new();
95        assert_eq!(os, NodeJsOs::Linux);
96    }
97
98    #[test]
99    fn it_initializes_with_defaults() {
100        let os = NodeJsOs::default();
101        assert_eq!(os, NodeJsOs::Linux);
102    }
103
104    #[test]
105    fn it_initializes_from_str() {
106        let os = NodeJsOs::from_str("linux").unwrap();
107
108        assert_eq!(os, NodeJsOs::Linux);
109
110        let os = NodeJsOs::from_str("darwin").unwrap();
111
112        assert_eq!(os, NodeJsOs::Darwin);
113
114        let os = NodeJsOs::from_str("macos").unwrap();
115
116        assert_eq!(os, NodeJsOs::Darwin);
117
118        let os = NodeJsOs::from_str("windows").unwrap();
119
120        assert_eq!(os, NodeJsOs::Windows);
121
122        let os = NodeJsOs::from_str("win").unwrap();
123
124        assert_eq!(os, NodeJsOs::Windows);
125
126        let os = NodeJsOs::from_str("aix").unwrap();
127
128        assert_eq!(os, NodeJsOs::Aix);
129
130        let os = NodeJsOs::from_str("sunos").unwrap();
131
132        assert_eq!(os, NodeJsOs::SunOs);
133
134        let os = NodeJsOs::from_str("solaris").unwrap();
135
136        assert_eq!(os, NodeJsOs::SunOs);
137    }
138
139    #[test]
140    fn it_serializes_to_str() {
141        let text = format!("{}", NodeJsOs::Linux);
142
143        assert_eq!(text, "linux");
144
145        let text = format!("{}", NodeJsOs::Darwin);
146
147        assert_eq!(text, "darwin");
148
149        let text = format!("{}", NodeJsOs::Windows);
150
151        assert_eq!(text, "win");
152
153        let text = format!("{}", NodeJsOs::Aix);
154
155        assert_eq!(text, "aix");
156
157        let text = format!("{}", NodeJsOs::SunOs);
158
159        assert_eq!(text, "sunos");
160    }
161
162    #[test]
163    fn it_initializes_using_current_environment() {
164        NodeJsOs::from_env().unwrap();
165    }
166
167    #[test]
168    fn it_fails_when_os_cannot_be_determined_from_str() {
169        let err = NodeJsOs::from_str("NOPE!").unwrap_err();
170        assert!(matches!(err, NodeJsRelInfoError::UnrecognizedOs(x) if x == "NOPE!"));
171    }
172
173    #[test]
174    #[cfg(feature = "json")]
175    fn it_serializes_and_deserializes() {
176        let os_json = serde_json::to_string(&NodeJsOs::Darwin).unwrap();
177        let os: NodeJsOs = serde_json::from_str(&os_json).unwrap();
178        assert_eq!(os, NodeJsOs::Darwin);
179    }
180}