os_ver/
lib.rs

1#[cfg(target_os = "ios")]
2pub mod ios;
3#[cfg(target_os = "linux")]
4pub mod linux;
5#[cfg(target_os = "macos")]
6pub mod macos;
7#[cfg(target_os = "windows")]
8pub mod windows;
9
10use std::sync::OnceLock;
11
12use cfg_if::cfg_if;
13
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
15pub struct Version {
16    pub major: u32,
17    pub minor: u32,
18    pub patch: u32,
19    pub build: u32,
20}
21
22type VersionTuple = (u32, u32, u32, u32);
23
24static OS_VERSION: OnceLock<Version> = OnceLock::new();
25
26pub fn os_version() -> &'static Version {
27    OS_VERSION.get_or_init(|| {
28        cfg_if! {
29            if #[cfg(target_os = "ios")] {
30                ios::get_version()
31            } else if #[cfg(target_os = "linux")] {
32                linux::get_version()
33            } else if #[cfg(target_os = "macos")] {
34                macos::get_version()
35            } else if #[cfg(target_os = "windows")] {
36                windows::get_version()
37            } else {
38                Version::default()
39            }
40        }
41    })
42}
43
44impl Version {
45    pub const fn new(major: u32, minor: u32, patch: u32, build: u32) -> Self {
46        Self {
47            major,
48            minor,
49            patch,
50            build,
51        }
52    }
53
54    pub const fn from((major, minor, patch, build): VersionTuple) -> Self {
55        Self {
56            major,
57            minor,
58            patch,
59            build,
60        }
61    }
62}
63
64impl From<Version> for VersionTuple {
65    fn from(version: Version) -> Self {
66        (version.major, version.minor, version.patch, version.build)
67    }
68}
69
70impl From<VersionTuple> for Version {
71    fn from(tuple: VersionTuple) -> Self {
72        Self::from(tuple)
73    }
74}
75
76#[macro_export]
77macro_rules! if_greater_than {
78    {($major:expr) => $block:block $(else $else_block:block)?} => {
79        if_greater_than!{($major, 0, 0, 0) => $block $(else {$else_block})?}
80    };
81    {($major:expr, $minor:expr) => $block:block $(else $else_block:block)?} => {
82        if_greater_than!{($major, $minor, 0, 0) => $block $(else {$else_block})?}
83    };
84    {($major:expr, $minor:expr, $patch:expr) => $block:block $(else $else_block:block)?} => {
85        if_greater_than!{($major, $minor, $patch, 0) => $block $(else {$else_block})?}
86    };
87    {($major:expr, $minor:expr, $patch:expr, $build:expr) => $block:block $(else $else_block:block)?} => {
88        if_greater_than!{os_ver::Version { major: $major, minor: $minor, patch: $patch, build: $build } => $block $(else {$else_block})?}
89    };
90    {$version:expr => $block:block $(else $else_block:block)?} => {
91        if os_ver::os_version() >= &$version {
92            $block
93        } $(else {
94            $else_block
95        })?
96    };
97}