1#![doc = include_str!("../README.md")]
2
3mod linux;
4pub use linux::Linux as LinuxOs;
5
6use std::str::FromStr;
7use strum::{AsRefStr, Display, EnumIs};
8
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[cfg_attr(feature = "rune", derive(rune::Any))]
11#[derive(Debug, Hash, Eq, Clone, Copy, Default, Display, EnumIs, AsRefStr, PartialEq)]
12#[strum(serialize_all = "snake_case")]
13pub enum Os {
14 #[default]
15 #[strum(serialize = "unknown")]
16 Unknown,
17 #[strum(transparent)]
18 Linux(LinuxOs),
19 #[strum(serialize = "windows")]
20 Windows,
21 #[strum(serialize = "macos")]
22 MacOs,
23 #[strum(serialize = "unix")]
24 Unix,
25}
26
27impl Os {
28 pub fn linux() -> Self {
29 Os::Linux(LinuxOs::default())
30 }
31 pub fn compatible(&self, other: &Os) -> bool {
42 match other {
43 Os::Unknown => true,
44 Os::Linux(LinuxOs::Unknown) => matches!(self, Os::Linux(_)),
45 Os::Linux(linux) => match self {
46 Os::Linux(other_linux) => linux == other_linux,
47 _ => false,
48 },
49 Os::Windows => self == &Os::Windows,
50 Os::MacOs => self == &Os::MacOs,
51 Os::Unix => matches!(self, Os::Linux(_) | Os::Unix | Os::MacOs),
52 }
53 }
54 pub fn next_compatible(&self) -> Option<Os> {
66 match self {
67 Os::Unknown => None,
68 Os::Linux(linux) if linux.is_unknown() => Some(Os::Unix),
69 Os::Linux(_) => Some(Os::linux()),
70 Os::Windows => Some(Os::Unknown), Os::MacOs => Some(Os::Unix), Os::Unix => Some(Os::Unknown), }
74 }
75}
76
77impl From<&str> for Os {
78 fn from(s: &str) -> Self {
79 if let Ok(os) = LinuxOs::from_str(s) {
80 Os::Linux(os)
81 } else {
82 match s {
83 "windows" => Os::Windows,
84 "macos" => Os::MacOs,
85 "unix" => Os::Unix,
86 _ => Os::Unknown,
87 }
88 }
89 }
90}
91
92impl From<&String> for Os {
93 fn from(s: &String) -> Self {
94 Os::from(s.as_str())
95 }
96}
97
98impl From<String> for Os {
99 fn from(s: String) -> Self {
100 Os::from(s.as_str())
101 }
102}
103pub fn detect() -> Os {
105 if cfg!(target_os = "linux") {
106 Os::Linux(LinuxOs::detect())
107 } else if cfg!(target_os = "windows") {
108 Os::Windows
109 } else if cfg!(target_os = "macos") {
110 Os::MacOs
111 } else {
112 Os::Unknown
113 }
114}
115
116#[test]
117fn test_os_convert() {
118 assert_eq!(Os::Unknown.as_ref(), "unknown");
119 assert_eq!(Os::Linux(LinuxOs::Unknown).as_ref(), "linux");
120 assert_eq!(Os::from("linux"), Os::Linux(LinuxOs::Unknown));
121 assert_eq!(Os::from("manjaro"), Os::Linux(LinuxOs::Manjaro));
122 assert_eq!(Os::from("unknown"), Os::Unknown);
123}