use std::fmt::Display;
use std::str::FromStr;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Version {
pub major: u32,
pub minor: u32,
pub patch: u32,
}
impl Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
}
}
impl PartialOrd for Version {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Version {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.major
.cmp(&other.major)
.then_with(|| self.minor.cmp(&other.minor))
.then_with(|| self.patch.cmp(&other.patch))
}
}
impl FromStr for Version {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
const E_SEG: &str = "expected three dot-separated segments";
const E_INT: &str = "expected segments to be unsigned integers";
let mut segs = s.splitn(3, '.');
let mut next = || segs.next().ok_or(E_SEG)?.parse().map_err(|_| E_INT);
Ok(Self { major: next()?, minor: next()?, patch: next()? })
}
}