Skip to main content

bare_types/sys/
os_type.rs

1//! Operating system type for system information.
2//!
3//! This module provides a type-safe abstraction for operating system types,
4//! ensuring valid OS identifiers and providing convenient constants
5//! for common operating systems.
6//!
7//! # Supported Operating Systems
8//!
9//! This type supports all major operating systems:
10//!
11//! - **Linux**: GNU/Linux distributions
12//! - **`MacOS`**: macOS (formerly OS X)
13//! - **Windows**: Microsoft Windows
14//! - **FreeBSD**: FreeBSD operating system
15//! - **OpenBSD**: OpenBSD operating system
16//! - **NetBSD**: NetBSD operating system
17//! - **`DragonFly`**: `DragonFly` BSD
18//! - **Solaris**: Oracle Solaris
19//! - **Illumos**: Illumos-based systems (`OpenIndiana`, etc.)
20//! - **Android**: Android mobile OS
21//! - **iOS**: Apple iOS
22//! - **Redox**: Redox OS (Rust-based)
23//! - **Fuchsia**: Google Fuchsia
24//! - **Hermit**: `HermitCore` unikernel
25//! - **`VxWorks`**: Wind River `VxWorks`
26//! - **AIX**: IBM AIX
27//! - **Haiku**: Haiku OS
28//!
29//! # Examples
30//!
31//! ```rust
32//! use bare_types::sys::OsType;
33//!
34//! // Get current OS (compile-time constant)
35//! let os = OsType::current();
36//!
37//! // Check OS family
38//! assert!(os.is_unix() || os.is_windows());
39//!
40//! // Parse from string
41//! let os: OsType = "linux".parse()?;
42//! assert_eq!(os, OsType::LINUX);
43//! # Ok::<(), bare_types::sys::OsTypeError>(())
44//! ```
45
46use core::fmt;
47use core::str::FromStr;
48
49#[cfg(feature = "serde")]
50use serde::{Deserialize, Serialize};
51
52#[cfg(feature = "arbitrary")]
53use arbitrary::Arbitrary;
54
55/// Error type for OS type parsing.
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
58pub enum OsTypeError {
59    /// Unknown operating system string
60    UnknownOperatingSystem,
61}
62
63impl fmt::Display for OsTypeError {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        match self {
66            Self::UnknownOperatingSystem => write!(f, "unknown operating system"),
67        }
68    }
69}
70
71#[cfg(feature = "std")]
72impl std::error::Error for OsTypeError {}
73
74/// Operating system type.
75///
76/// This enum provides type-safe operating system identifiers.
77/// All variants are validated at construction time.
78///
79/// # Invariants
80///
81/// - All variants represent valid operating systems
82/// - OS type is determined at compile time for `current()` method
83///
84/// # Examples
85///
86/// ```rust
87/// use bare_types::sys::OsType;
88///
89/// // Use predefined constants
90/// let os = OsType::LINUX;
91/// assert!(os.is_unix());
92///
93/// // Get current OS
94/// let current = OsType::current();
95/// println!("Running on: {}", current);
96///
97/// // Convert to string representation
98/// assert_eq!(OsType::LINUX.as_str(), "linux");
99/// # Ok::<(), bare_types::sys::OsTypeError>(())
100/// ```
101#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
102#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
103#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
104#[non_exhaustive]
105pub enum OsType {
106    /// GNU/Linux distributions
107    LINUX,
108    /// macOS (formerly OS X)
109    MACOS,
110    /// Microsoft Windows
111    WINDOWS,
112    /// FreeBSD operating system
113    FREEBSD,
114    /// OpenBSD operating system
115    OPENBSD,
116    /// NetBSD operating system
117    NETBSD,
118    /// `DragonFly` BSD
119    DRAGONFLY,
120    /// Oracle Solaris
121    SOLARIS,
122    /// Illumos-based systems (`OpenIndiana`, `SmartOS`, etc.)
123    ILLUMOS,
124    /// Android mobile OS
125    ANDROID,
126    /// Apple iOS
127    IOS,
128    /// Redox OS (Rust-based microkernel)
129    REDOX,
130    /// Google Fuchsia
131    FUCHSIA,
132    /// `HermitCore` unikernel
133    HERMIT,
134    /// Wind River `VxWorks`
135    VXWORKS,
136    /// IBM AIX
137    AIX,
138    /// Haiku OS (BeOS-inspired)
139    HAIKU,
140}
141
142impl OsType {
143    /// Returns the current operating system (compile-time constant).
144    ///
145    /// This method returns the operating system the code was compiled for,
146    /// not necessarily the OS of the host system (especially relevant for
147    /// cross-compilation).
148    ///
149    /// # Examples
150    ///
151    /// ```rust
152    /// use bare_types::sys::OsType;
153    ///
154    /// let os = OsType::current();
155    /// println!("Compiled for: {}", os);
156    /// ```
157    #[must_use]
158    pub const fn current() -> Self {
159        #[cfg(target_os = "linux")]
160        return Self::LINUX;
161        #[cfg(target_os = "macos")]
162        return Self::MACOS;
163        #[cfg(target_os = "windows")]
164        return Self::WINDOWS;
165        #[cfg(target_os = "freebsd")]
166        return Self::FREEBSD;
167        #[cfg(target_os = "openbsd")]
168        return Self::OPENBSD;
169        #[cfg(target_os = "netbsd")]
170        return Self::NETBSD;
171        #[cfg(target_os = "dragonfly")]
172        return Self::DRAGONFLY;
173        #[cfg(target_os = "solaris")]
174        return Self::SOLARIS;
175        #[cfg(target_os = "illumos")]
176        return Self::ILLUMOS;
177        #[cfg(target_os = "android")]
178        return Self::ANDROID;
179        #[cfg(target_os = "ios")]
180        return Self::IOS;
181        #[cfg(target_os = "redox")]
182        return Self::REDOX;
183        #[cfg(target_os = "fuchsia")]
184        return Self::FUCHSIA;
185        #[cfg(target_os = "hermit")]
186        return Self::HERMIT;
187        #[cfg(target_os = "vxworks")]
188        return Self::VXWORKS;
189        #[cfg(target_os = "aix")]
190        return Self::AIX;
191        #[cfg(target_os = "haiku")]
192        return Self::HAIKU;
193        #[cfg(not(any(
194            target_os = "linux",
195            target_os = "macos",
196            target_os = "windows",
197            target_os = "freebsd",
198            target_os = "openbsd",
199            target_os = "netbsd",
200            target_os = "dragonfly",
201            target_os = "solaris",
202            target_os = "illumos",
203            target_os = "android",
204            target_os = "ios",
205            target_os = "redox",
206            target_os = "fuchsia",
207            target_os = "hermit",
208            target_os = "vxworks",
209            target_os = "aix",
210            target_os = "haiku",
211        )))]
212        {
213            panic!("unsupported target operating system")
214        }
215    }
216
217    /// Returns the string representation of this OS.
218    ///
219    /// # Examples
220    ///
221    /// ```rust
222    /// use bare_types::sys::OsType;
223    ///
224    /// assert_eq!(OsType::LINUX.as_str(), "linux");
225    /// assert_eq!(OsType::MACOS.as_str(), "macos");
226    /// assert_eq!(OsType::WINDOWS.as_str(), "windows");
227    /// ```
228    #[must_use]
229    pub const fn as_str(&self) -> &'static str {
230        match self {
231            Self::LINUX => "linux",
232            Self::MACOS => "macos",
233            Self::WINDOWS => "windows",
234            Self::FREEBSD => "freebsd",
235            Self::OPENBSD => "openbsd",
236            Self::NETBSD => "netbsd",
237            Self::DRAGONFLY => "dragonfly",
238            Self::SOLARIS => "solaris",
239            Self::ILLUMOS => "illumos",
240            Self::ANDROID => "android",
241            Self::IOS => "ios",
242            Self::REDOX => "redox",
243            Self::FUCHSIA => "fuchsia",
244            Self::HERMIT => "hermit",
245            Self::VXWORKS => "vxworks",
246            Self::AIX => "aix",
247            Self::HAIKU => "haiku",
248        }
249    }
250
251    /// Returns `true` if this is a Unix-like operating system.
252    ///
253    /// # Examples
254    ///
255    /// ```rust
256    /// use bare_types::sys::OsType;
257    ///
258    /// assert!(OsType::LINUX.is_unix());
259    /// assert!(OsType::MACOS.is_unix());
260    /// assert!(OsType::FREEBSD.is_unix());
261    /// assert!(!OsType::WINDOWS.is_unix());
262    /// ```
263    #[must_use]
264    pub const fn is_unix(&self) -> bool {
265        matches!(
266            self,
267            Self::LINUX
268                | Self::MACOS
269                | Self::FREEBSD
270                | Self::OPENBSD
271                | Self::NETBSD
272                | Self::DRAGONFLY
273                | Self::SOLARIS
274                | Self::ILLUMOS
275                | Self::ANDROID
276                | Self::IOS
277                | Self::AIX
278                | Self::HAIKU
279        )
280    }
281
282    /// Returns `true` if this is a BSD operating system.
283    ///
284    /// # Examples
285    ///
286    /// ```rust
287    /// use bare_types::sys::OsType;
288    ///
289    /// assert!(OsType::FREEBSD.is_bsd());
290    /// assert!(OsType::OPENBSD.is_bsd());
291    /// assert!(OsType::NETBSD.is_bsd());
292    /// assert!(OsType::DRAGONFLY.is_bsd());
293    /// assert!(OsType::MACOS.is_bsd());
294    /// assert!(!OsType::LINUX.is_bsd());
295    /// assert!(!OsType::WINDOWS.is_bsd());
296    /// ```
297    #[must_use]
298    pub const fn is_bsd(&self) -> bool {
299        matches!(
300            self,
301            Self::FREEBSD | Self::OPENBSD | Self::NETBSD | Self::DRAGONFLY | Self::MACOS
302        )
303    }
304
305    /// Returns `true` if this is Microsoft Windows.
306    ///
307    /// # Examples
308    ///
309    /// ```rust
310    /// use bare_types::sys::OsType;
311    ///
312    /// assert!(OsType::WINDOWS.is_windows());
313    /// assert!(!OsType::LINUX.is_windows());
314    /// assert!(!OsType::MACOS.is_windows());
315    /// ```
316    #[must_use]
317    pub const fn is_windows(&self) -> bool {
318        matches!(self, Self::WINDOWS)
319    }
320
321    /// Returns `true` if this is a mobile operating system.
322    ///
323    /// # Examples
324    ///
325    /// ```rust
326    /// use bare_types::sys::OsType;
327    ///
328    /// assert!(OsType::ANDROID.is_mobile());
329    /// assert!(OsType::IOS.is_mobile());
330    /// assert!(!OsType::LINUX.is_mobile());
331    /// assert!(!OsType::WINDOWS.is_mobile());
332    /// ```
333    #[must_use]
334    pub const fn is_mobile(&self) -> bool {
335        matches!(self, Self::ANDROID | Self::IOS)
336    }
337
338    /// Returns `true` if this is a desktop operating system.
339    ///
340    /// # Examples
341    ///
342    /// ```rust
343    /// use bare_types::sys::OsType;
344    ///
345    /// assert!(OsType::LINUX.is_desktop());
346    /// assert!(OsType::MACOS.is_desktop());
347    /// assert!(OsType::WINDOWS.is_desktop());
348    /// assert!(!OsType::ANDROID.is_desktop());
349    /// assert!(!OsType::IOS.is_desktop());
350    /// ```
351    #[must_use]
352    pub const fn is_desktop(&self) -> bool {
353        matches!(
354            self,
355            Self::LINUX | Self::MACOS | Self::WINDOWS | Self::FREEBSD | Self::HAIKU
356        )
357    }
358
359    /// Returns `true` if this is an embedded/real-time operating system.
360    ///
361    /// # Examples
362    ///
363    /// ```rust
364    /// use bare_types::sys::OsType;
365    ///
366    /// assert!(OsType::VXWORKS.is_embedded());
367    /// assert!(!OsType::LINUX.is_embedded());
368    /// ```
369    #[must_use]
370    pub const fn is_embedded(&self) -> bool {
371        matches!(self, Self::VXWORKS)
372    }
373
374    /// Returns `true` if this is a microkernel-based operating system.
375    ///
376    /// # Examples
377    ///
378    /// ```rust
379    /// use bare_types::sys::OsType;
380    ///
381    /// assert!(OsType::REDOX.is_microkernel());
382    /// assert!(OsType::FUCHSIA.is_microkernel());
383    /// assert!(!OsType::LINUX.is_microkernel());
384    /// ```
385    #[must_use]
386    pub const fn is_microkernel(&self) -> bool {
387        matches!(self, Self::REDOX | Self::FUCHSIA)
388    }
389
390    /// Returns `true` if this OS supports POSIX APIs.
391    ///
392    /// # Examples
393    ///
394    /// ```rust
395    /// use bare_types::sys::OsType;
396    ///
397    /// assert!(OsType::LINUX.is_posix());
398    /// assert!(OsType::MACOS.is_posix());
399    /// assert!(!OsType::WINDOWS.is_posix());
400    /// ```
401    #[must_use]
402    pub const fn is_posix(&self) -> bool {
403        self.is_unix()
404    }
405
406    /// Returns `true` if this is a tier 1 supported Rust target.
407    ///
408    /// Tier 1 targets are guaranteed to work with Rust.
409    ///
410    /// # Examples
411    ///
412    /// ```rust
413    /// use bare_types::sys::OsType;
414    ///
415    /// assert!(OsType::LINUX.is_tier1());
416    /// assert!(OsType::MACOS.is_tier1());
417    /// assert!(OsType::WINDOWS.is_tier1());
418    /// // Tier 2/3 targets return false
419    /// // assert!(!OsType::FREEBSD.is_tier1());
420    /// ```
421    #[must_use]
422    pub const fn is_tier1(&self) -> bool {
423        matches!(self, Self::LINUX | Self::MACOS | Self::WINDOWS)
424    }
425
426    /// Returns the family of this OS as a string.
427    ///
428    /// # Examples
429    ///
430    /// ```rust
431    /// use bare_types::sys::OsType;
432    ///
433    /// assert_eq!(OsType::LINUX.family(), "unix");
434    /// assert_eq!(OsType::MACOS.family(), "unix");
435    /// assert_eq!(OsType::WINDOWS.family(), "windows");
436    /// ```
437    #[must_use]
438    pub const fn family(&self) -> &'static str {
439        if self.is_unix() {
440            "unix"
441        } else if self.is_windows() {
442            "windows"
443        } else {
444            "unknown"
445        }
446    }
447}
448
449impl TryFrom<&str> for OsType {
450    type Error = OsTypeError;
451
452    fn try_from(s: &str) -> Result<Self, Self::Error> {
453        s.parse()
454    }
455}
456
457impl FromStr for OsType {
458    type Err = OsTypeError;
459
460    fn from_str(s: &str) -> Result<Self, Self::Err> {
461        match s.to_lowercase().as_str() {
462            "linux" => Ok(Self::LINUX),
463            "macos" | "mac" | "osx" | "darwin" | "os x" => Ok(Self::MACOS),
464            "windows" | "win" => Ok(Self::WINDOWS),
465            "freebsd" => Ok(Self::FREEBSD),
466            "openbsd" => Ok(Self::OPENBSD),
467            "netbsd" => Ok(Self::NETBSD),
468            "dragonfly" | "dragonfly bsd" => Ok(Self::DRAGONFLY),
469            "solaris" => Ok(Self::SOLARIS),
470            "illumos" => Ok(Self::ILLUMOS),
471            "android" => Ok(Self::ANDROID),
472            "ios" | "iphone" => Ok(Self::IOS),
473            "redox" => Ok(Self::REDOX),
474            "fuchsia" => Ok(Self::FUCHSIA),
475            "hermit" => Ok(Self::HERMIT),
476            "vxworks" => Ok(Self::VXWORKS),
477            "aix" => Ok(Self::AIX),
478            "haiku" => Ok(Self::HAIKU),
479            _ => Err(OsTypeError::UnknownOperatingSystem),
480        }
481    }
482}
483
484impl fmt::Display for OsType {
485    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
486        write!(f, "{}", self.as_str())
487    }
488}
489
490#[cfg(test)]
491mod tests {
492    use super::*;
493
494    #[test]
495    fn test_as_str() {
496        assert_eq!(OsType::LINUX.as_str(), "linux");
497        assert_eq!(OsType::MACOS.as_str(), "macos");
498        assert_eq!(OsType::WINDOWS.as_str(), "windows");
499        assert_eq!(OsType::FREEBSD.as_str(), "freebsd");
500        assert_eq!(OsType::OPENBSD.as_str(), "openbsd");
501        assert_eq!(OsType::NETBSD.as_str(), "netbsd");
502        assert_eq!(OsType::DRAGONFLY.as_str(), "dragonfly");
503        assert_eq!(OsType::SOLARIS.as_str(), "solaris");
504        assert_eq!(OsType::ILLUMOS.as_str(), "illumos");
505        assert_eq!(OsType::ANDROID.as_str(), "android");
506        assert_eq!(OsType::IOS.as_str(), "ios");
507        assert_eq!(OsType::REDOX.as_str(), "redox");
508        assert_eq!(OsType::FUCHSIA.as_str(), "fuchsia");
509        assert_eq!(OsType::HERMIT.as_str(), "hermit");
510        assert_eq!(OsType::VXWORKS.as_str(), "vxworks");
511        assert_eq!(OsType::AIX.as_str(), "aix");
512        assert_eq!(OsType::HAIKU.as_str(), "haiku");
513    }
514
515    #[test]
516    fn test_is_unix() {
517        assert!(OsType::LINUX.is_unix());
518        assert!(OsType::MACOS.is_unix());
519        assert!(OsType::FREEBSD.is_unix());
520        assert!(OsType::OPENBSD.is_unix());
521        assert!(OsType::NETBSD.is_unix());
522        assert!(OsType::DRAGONFLY.is_unix());
523        assert!(OsType::SOLARIS.is_unix());
524        assert!(OsType::ILLUMOS.is_unix());
525        assert!(OsType::ANDROID.is_unix());
526        assert!(OsType::IOS.is_unix());
527        assert!(OsType::AIX.is_unix());
528        assert!(OsType::HAIKU.is_unix());
529        assert!(!OsType::WINDOWS.is_unix());
530        assert!(!OsType::REDOX.is_unix());
531        assert!(!OsType::FUCHSIA.is_unix());
532    }
533
534    #[test]
535    fn test_is_bsd() {
536        assert!(OsType::FREEBSD.is_bsd());
537        assert!(OsType::OPENBSD.is_bsd());
538        assert!(OsType::NETBSD.is_bsd());
539        assert!(OsType::DRAGONFLY.is_bsd());
540        assert!(OsType::MACOS.is_bsd());
541        assert!(!OsType::LINUX.is_bsd());
542        assert!(!OsType::WINDOWS.is_bsd());
543    }
544
545    #[test]
546    fn test_is_windows() {
547        assert!(OsType::WINDOWS.is_windows());
548        assert!(!OsType::LINUX.is_windows());
549        assert!(!OsType::MACOS.is_windows());
550    }
551
552    #[test]
553    fn test_is_mobile() {
554        assert!(OsType::ANDROID.is_mobile());
555        assert!(OsType::IOS.is_mobile());
556        assert!(!OsType::LINUX.is_mobile());
557        assert!(!OsType::WINDOWS.is_mobile());
558    }
559
560    #[test]
561    fn test_is_desktop() {
562        assert!(OsType::LINUX.is_desktop());
563        assert!(OsType::MACOS.is_desktop());
564        assert!(OsType::WINDOWS.is_desktop());
565        assert!(OsType::FREEBSD.is_desktop());
566        assert!(OsType::HAIKU.is_desktop());
567        assert!(!OsType::ANDROID.is_desktop());
568        assert!(!OsType::IOS.is_desktop());
569    }
570
571    #[test]
572    fn test_is_embedded() {
573        assert!(OsType::VXWORKS.is_embedded());
574        assert!(!OsType::LINUX.is_embedded());
575    }
576
577    #[test]
578    fn test_is_microkernel() {
579        assert!(OsType::REDOX.is_microkernel());
580        assert!(OsType::FUCHSIA.is_microkernel());
581        assert!(!OsType::LINUX.is_microkernel());
582    }
583
584    #[test]
585    fn test_is_posix() {
586        assert!(OsType::LINUX.is_posix());
587        assert!(OsType::MACOS.is_posix());
588        assert!(!OsType::WINDOWS.is_posix());
589    }
590
591    #[test]
592    fn test_is_tier1() {
593        assert!(OsType::LINUX.is_tier1());
594        assert!(OsType::MACOS.is_tier1());
595        assert!(OsType::WINDOWS.is_tier1());
596        assert!(!OsType::FREEBSD.is_tier1());
597    }
598
599    #[test]
600    fn test_family() {
601        assert_eq!(OsType::LINUX.family(), "unix");
602        assert_eq!(OsType::MACOS.family(), "unix");
603        assert_eq!(OsType::WINDOWS.family(), "windows");
604    }
605
606    #[test]
607    fn test_from_str() {
608        assert_eq!("linux".parse::<OsType>().unwrap(), OsType::LINUX);
609        assert_eq!("macos".parse::<OsType>().unwrap(), OsType::MACOS);
610        assert_eq!("mac".parse::<OsType>().unwrap(), OsType::MACOS);
611        assert_eq!("darwin".parse::<OsType>().unwrap(), OsType::MACOS);
612        assert_eq!("windows".parse::<OsType>().unwrap(), OsType::WINDOWS);
613        assert_eq!("freebsd".parse::<OsType>().unwrap(), OsType::FREEBSD);
614        assert_eq!("openbsd".parse::<OsType>().unwrap(), OsType::OPENBSD);
615        assert_eq!("netbsd".parse::<OsType>().unwrap(), OsType::NETBSD);
616        assert_eq!("dragonfly".parse::<OsType>().unwrap(), OsType::DRAGONFLY);
617        assert_eq!("solaris".parse::<OsType>().unwrap(), OsType::SOLARIS);
618        assert_eq!("illumos".parse::<OsType>().unwrap(), OsType::ILLUMOS);
619        assert_eq!("android".parse::<OsType>().unwrap(), OsType::ANDROID);
620        assert_eq!("ios".parse::<OsType>().unwrap(), OsType::IOS);
621        assert_eq!("redox".parse::<OsType>().unwrap(), OsType::REDOX);
622        assert_eq!("fuchsia".parse::<OsType>().unwrap(), OsType::FUCHSIA);
623        assert_eq!("hermit".parse::<OsType>().unwrap(), OsType::HERMIT);
624        assert_eq!("vxworks".parse::<OsType>().unwrap(), OsType::VXWORKS);
625        assert_eq!("aix".parse::<OsType>().unwrap(), OsType::AIX);
626        assert_eq!("haiku".parse::<OsType>().unwrap(), OsType::HAIKU);
627
628        // Test case insensitivity
629        assert_eq!("LINUX".parse::<OsType>().unwrap(), OsType::LINUX);
630        assert_eq!("Windows".parse::<OsType>().unwrap(), OsType::WINDOWS);
631    }
632
633    #[test]
634    fn test_from_str_error() {
635        assert!("unknown".parse::<OsType>().is_err());
636        assert!("".parse::<OsType>().is_err());
637    }
638
639    #[test]
640    fn test_display() {
641        assert_eq!(format!("{}", OsType::LINUX), "linux");
642        assert_eq!(format!("{}", OsType::MACOS), "macos");
643        assert_eq!(format!("{}", OsType::WINDOWS), "windows");
644    }
645
646    #[test]
647    fn test_current() {
648        // Just verify it doesn't panic
649        let _os = OsType::current();
650    }
651
652    #[test]
653    fn test_copy() {
654        let os = OsType::LINUX;
655        let os2 = os;
656        assert_eq!(os, os2);
657    }
658
659    #[test]
660    fn test_clone() {
661        let os = OsType::LINUX;
662        let os2 = os.clone();
663        assert_eq!(os, os2);
664    }
665
666    #[test]
667    fn test_equality() {
668        assert_eq!(OsType::LINUX, OsType::LINUX);
669        assert_ne!(OsType::LINUX, OsType::WINDOWS);
670    }
671
672    #[test]
673    fn test_ordering() {
674        assert!(OsType::LINUX < OsType::ANDROID); // LINUX defined before ANDROID in enum
675        assert!(OsType::LINUX < OsType::FREEBSD); // LINUX defined before FREEBSD
676    }
677}