cargo_apple_runner/
version.rs1use 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}