1use anyhow::Result;
2use std::fmt;
3
4mod linux;
5pub use crate::linux::Linux;
6mod macos;
7pub use crate::macos::MacOS;
8mod windows;
9pub use crate::windows::Windows;
10mod android;
11pub use crate::android::Android;
12mod openbsd;
13pub use crate::openbsd::OpenBSD;
14
15#[cfg(target_os = "windows")]
16mod winapi;
17
18#[cfg(feature = "tokio")]
19pub mod tokio;
20
21pub fn detect() -> Result<OsVersion> {
22 if cfg!(target_os = "linux") {
23 Ok(OsVersion::Linux(Linux::detect()?))
24 } else if cfg!(target_os = "macos") {
25 Ok(OsVersion::MacOS(MacOS::detect()?))
26 } else if cfg!(target_os = "windows") {
27 Ok(OsVersion::Windows(Windows::detect()?))
28 } else if cfg!(target_os = "android") {
29 Ok(OsVersion::Android(Android::detect()?))
30 } else if cfg!(target_os = "openbsd") {
31 Ok(OsVersion::OpenBSD(OpenBSD::detect()?))
32 } else {
33 Ok(OsVersion::Unknown)
34 }
35}
36
37#[derive(Debug, Clone, PartialEq)]
38#[non_exhaustive]
39pub enum OsVersion {
40 Linux(Linux),
41 MacOS(MacOS),
42 Windows(Windows),
43 Android(Android),
44 OpenBSD(OpenBSD),
45 Unknown,
46}
47
48impl fmt::Display for OsVersion {
49 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
50 match self {
51 OsVersion::Linux(v) => v.fmt(w),
52 OsVersion::MacOS(v) => v.fmt(w),
53 OsVersion::Windows(v) => v.fmt(w),
54 OsVersion::Android(v) => v.fmt(w),
55 OsVersion::OpenBSD(v) => v.fmt(w),
56 OsVersion::Unknown => write!(w, "unknown"),
57 }
58 }
59}