#![no_std]
use core::cmp::Ordering;
use core::fmt;
use core::{
option::Option::{self, Some},
write,
env,
prelude::rust_2021::derive,
cmp::{Ord, PartialOrd, PartialEq, Eq}
};
#[derive(Debug, PartialEq, Eq)]
pub enum VersionType {
Release,
Beta(u16),
Alpha(u16),
}
#[derive(Debug, PartialEq, Eq)]
pub struct Version {
major: u16,
minor: u16,
patch: u16,
version_type: VersionType,
}
impl Version {
pub fn new(major: u16, minor: u16, patch: u16) -> Self {
Self {
major,
minor,
patch,
version_type: VersionType::Release,
}
}
pub fn from_pkg() -> Self {
let version_str = env!("CARGO_PKG_VERSION");
let mut version_parts = version_str.split('.').map(|s| s.parse::<u16>().unwrap());
Self {
major: version_parts.next().unwrap(),
minor: version_parts.next().unwrap(),
patch: version_parts.next().unwrap(),
version_type: VersionType::Release,
}
}
pub fn release(mut self) -> Self {
self.version_type = VersionType::Release;
self
}
pub fn beta(mut self, beta_number: u16) -> Self {
self.version_type = VersionType::Beta(beta_number);
self
}
pub fn alpha(mut self, alpha_number: u16) -> Self {
self.version_type = VersionType::Alpha(alpha_number);
self
}
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.version_type {
VersionType::Release => write!(f, "v{}.{}.{}-release", self.major, self.minor, self.patch),
VersionType::Beta(0) => write!(f, "v{}.{}.{}-beta", self.major, self.minor, self.patch),
VersionType::Beta(number) => write!(f, "v{}.{}.{}-beta{}", self.major, self.minor, self.patch, number),
VersionType::Alpha(0) => write!(f, "v{}.{}.{}-alpha", self.major, self.minor, self.patch),
VersionType::Alpha(number) => write!(f, "v{}.{}.{}-alpha{}", self.major, self.minor, self.patch, number),
}
}
}
impl Ord for Version {
fn cmp(&self, other: &Self) -> Ordering {
let cmp = self.major.cmp(&other.major)
.then_with(|| self.minor.cmp(&other.minor))
.then_with(|| self.patch.cmp(&other.patch));
if cmp != Ordering::Equal {
return cmp;
}
match (&self.version_type, &other.version_type) {
(VersionType::Release, VersionType::Release) => Ordering::Equal,
(VersionType::Release, _) => Ordering::Greater,
(_, VersionType::Release) => Ordering::Less,
(VersionType::Beta(a), VersionType::Beta(b)) => a.cmp(b),
(VersionType::Beta(_), VersionType::Alpha(_)) => Ordering::Greater,
(VersionType::Alpha(_), VersionType::Beta(_)) => Ordering::Less,
(VersionType::Alpha(a), VersionType::Alpha(b)) => a.cmp(b),
}
}
}
impl PartialOrd for Version {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}