Skip to main content

cargo_apple_runner/
version.rs

1use core::fmt;
2use std::str::FromStr;
3
4use anyhow::Context;
5
6#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
7pub struct OSVersion {
8    pub major: u16,
9    pub minor: u8,
10    pub patch: u8,
11}
12
13impl OSVersion {
14    pub const MIN: Self = Self::from_packed(u32::MIN);
15    pub const MAX: Self = Self::from_packed(u32::MAX);
16
17    pub const fn from_packed(packed: u32) -> Self {
18        let major = ((packed >> 16) & 0xFFFF) as u16;
19        let minor = ((packed >> 8) & 0xFF) as u8;
20        let patch = (packed & 0xFF) as u8;
21
22        Self {
23            major,
24            minor,
25            patch,
26        }
27    }
28}
29
30impl FromStr for OSVersion {
31    type Err = anyhow::Error;
32
33    fn from_str(s: &str) -> Result<Self, Self::Err> {
34        let (major, rest) = s.split_once('.').context("missing version separator")?;
35        let major: u16 = major.parse()?;
36        if let Some((minor, patch)) = rest.split_once('.') {
37            let minor: u8 = minor.parse()?;
38            let patch: u8 = patch.parse()?;
39            Ok(Self {
40                major,
41                minor,
42                patch,
43            })
44        } else {
45            let minor: u8 = rest.parse()?;
46            Ok(Self {
47                major,
48                minor,
49                patch: 0,
50            })
51        }
52    }
53}
54
55impl fmt::Display for OSVersion {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        write!(f, "{}.{}", self.major, self.minor)?;
58        if self.patch != 0 {
59            write!(f, ".{}", self.patch)?;
60        }
61        Ok(())
62    }
63}