use std::mem;
use version::Version;
use self::OsRelease::*;
const MIN_MINOR_VERSION: u64 = 7; const MAX_MINOR_VERSION: u64 = MIN_MINOR_VERSION + OsRelease::LATEST as u64;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum OsRelease {
Lion,
MountainLion,
Mavericks,
Yosemite,
ElCapitan,
Sierra,
HighSierra,
Mojave,
#[doc(hidden)]
_NonExhaustive,
}
impl<'a> From<OsRelease> for &'a str {
fn from(release: OsRelease) -> Self {
match release {
Lion => "Lion",
MountainLion => "Mountain Lion",
Mavericks => "Mavericks",
Yosemite => "Yosemite",
ElCapitan => "El Capitan",
Sierra => "Sierra",
HighSierra => "High Sierra",
Mojave => "Mojave",
_NonExhaustive => unsafe { std::hint::unreachable_unchecked() },
}
}
}
impl OsRelease {
pub const MIN: OsRelease = Lion;
pub const LATEST: OsRelease = Mojave;
pub fn new<V: Into<Version>>(version: V) -> Option<Self> {
let Version { major, minor, .. } = version.into();
match (major, minor) {
(10, MIN_MINOR_VERSION..=MAX_MINOR_VERSION) => unsafe {
Some(mem::transmute((minor - MIN_MINOR_VERSION) as u8))
},
_ => None,
}
}
}
impl From<OsRelease> for Version {
fn from(release: OsRelease) -> Version {
(10, MIN_MINOR_VERSION + release as u64).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn version_conversion() {
let minor_end = MAX_MINOR_VERSION + 1;
let major = 10;
assert_eq!(OsRelease::new((major, minor_end)), None);
for minor in MIN_MINOR_VERSION..minor_end {
let vers = Version::from((major, minor));
let name = OsRelease::new(vers).unwrap();
assert_eq!(Version::from(name), vers);
}
}
#[test]
fn cmp() {
assert!(OsRelease::LATEST > OsRelease::MIN);
}
}