use sysexits::ExitCode;
#[derive(Debug, PartialEq, Eq)]
pub struct Version {
major: usize,
minor: usize,
patch: usize,
}
impl Version {
crate::getters!(@fn @cp
major: usize,
minor: usize,
patch: usize
);
#[must_use]
pub const fn new(major: usize, minor: usize, patch: usize) -> Self {
Self {
major,
minor,
patch,
}
}
pub fn set_major(&mut self, major: usize) {
self.major = major;
}
pub fn set_minor(&mut self, minor: usize) {
self.minor = minor;
}
pub fn set_patch(&mut self, patch: usize) {
self.patch = patch;
}
}
impl std::fmt::Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "v{}.{}.{}", self.major, self.minor, self.patch)
}
}
impl std::str::FromStr for Version {
type Err = ExitCode;
fn from_str(string: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = if string.starts_with('v') {
string.strip_prefix('v').unwrap()
} else {
string
}
.split('.')
.collect();
let (major_version, minor_version, patch_level) = match parts.len() {
1 => (parts[0].parse::<usize>(), Ok(0), Ok(0)),
2 => (parts[0].parse::<usize>(), parts[1].parse::<usize>(), Ok(0)),
_ => (
parts[0].parse::<usize>(),
parts[1].parse::<usize>(),
parts[2].parse::<usize>(),
),
};
match (major_version, minor_version, patch_level) {
(Ok(major), Ok(minor), Ok(patch)) => Ok(Self {
major,
minor,
patch,
}),
_ => Err(ExitCode::DataErr),
}
}
}