Add Rapid
and Simple
versioning, fix logic error in Extended
This commit is contained in:
parent
31d3bc960b
commit
88de80e0d3
@ -37,7 +37,7 @@ impl FromStr for Extended {
|
||||
};
|
||||
let split = s.split('.').collect::<Vec<_>>();
|
||||
match split.len() {
|
||||
3 => {
|
||||
4 => {
|
||||
let major = split.first().unwrap().parse::<u16>()?;
|
||||
let minor = split.get(1).unwrap().parse::<u16>()?;
|
||||
let patch = split.get(2).unwrap().parse::<u16>()?;
|
||||
|
@ -1,8 +1,13 @@
|
||||
mod error;
|
||||
mod extended;
|
||||
mod prerelease;
|
||||
mod rapid;
|
||||
mod semver;
|
||||
mod simple;
|
||||
|
||||
pub use {error::Error, extended::Extended, prerelease::PreRelease, semver::SemVer};
|
||||
pub use {
|
||||
error::Error, extended::Extended, prerelease::PreRelease, rapid::Rapid, semver::SemVer,
|
||||
simple::Simple,
|
||||
};
|
||||
|
||||
pub static MAX_U12: u16 = 4096;
|
||||
|
95
src/rapid.rs
95
src/rapid.rs
@ -0,0 +1,95 @@
|
||||
use {
|
||||
crate::{Error, PreRelease, MAX_U12},
|
||||
serde::{Deserialize, Serialize},
|
||||
std::{cmp::Ordering, fmt, str::FromStr},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||
pub struct Rapid {
|
||||
pub major: u16,
|
||||
pub minor: u16,
|
||||
pub pre: PreRelease,
|
||||
}
|
||||
|
||||
impl fmt::Display for Rapid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}.{}", self.major, self.minor)?;
|
||||
match self.pre {
|
||||
PreRelease::None => Ok(()),
|
||||
p => write!(f, "_{p}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Rapid {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let (s, pre) = match s.split_once('_') {
|
||||
Some((a, b)) => (a, b.parse::<PreRelease>()?),
|
||||
None => (s, PreRelease::None),
|
||||
};
|
||||
let split = s.split('.').collect::<Vec<_>>();
|
||||
match split.len() {
|
||||
2 => {
|
||||
let major = split.first().unwrap().parse::<u16>()?;
|
||||
let minor = split.get(1).unwrap().parse::<u16>()?;
|
||||
if major > MAX_U12 || minor > MAX_U12 {
|
||||
return Err(Error::Range);
|
||||
}
|
||||
Ok(Self { major, minor, pre })
|
||||
}
|
||||
_ => Err(Error::ParseSemver),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rapid> for u64 {
|
||||
fn from(value: Rapid) -> Self {
|
||||
let major = u64::from(value.major) << 52;
|
||||
let minor = u64::from(value.minor) << 40;
|
||||
let pre = u64::from(u16::from(value.pre));
|
||||
major | minor | pre
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u64> for Rapid {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u64) -> Result<Self, Self::Error> {
|
||||
let mut mask: u64 = 0o7777 << 52;
|
||||
let major = (value & mask) >> 52;
|
||||
mask = 0o7777 << 40;
|
||||
let minor = (value & mask) >> 40;
|
||||
mask = 0o37777;
|
||||
let p = u16::try_from(value & mask)?;
|
||||
let pre: PreRelease = p.try_into()?;
|
||||
Ok(Self {
|
||||
major: major.try_into()?,
|
||||
minor: minor.try_into()?,
|
||||
pre,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Rapid {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.major == other.major && self.minor == other.minor && self.pre == other.pre
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Rapid {}
|
||||
|
||||
impl Ord for Rapid {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
let a = u64::from(*self);
|
||||
let b = u64::from(*other);
|
||||
a.cmp(&b)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Rapid {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
use {
|
||||
crate::{Error, PreRelease, MAX_U12},
|
||||
serde::{Deserialize, Serialize},
|
||||
std::{cmp::Ordering, fmt, str::FromStr},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||
pub struct Simple {
|
||||
pub major: u16,
|
||||
pub pre: PreRelease,
|
||||
}
|
||||
|
||||
impl fmt::Display for Simple {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.major)?;
|
||||
match self.pre {
|
||||
PreRelease::None => Ok(()),
|
||||
p => write!(f, "_{p}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Simple {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let (s, pre) = match s.split_once('_') {
|
||||
Some((a, b)) => (a, b.parse::<PreRelease>()?),
|
||||
None => (s, PreRelease::None),
|
||||
};
|
||||
let major = s.parse::<u16>()?;
|
||||
if major > MAX_U12 {
|
||||
return Err(Error::Range);
|
||||
}
|
||||
Ok(Self { major, pre })
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Simple> for u64 {
|
||||
fn from(value: Simple) -> Self {
|
||||
let major = u64::from(value.major) << 52;
|
||||
let pre = u64::from(u16::from(value.pre));
|
||||
major | pre
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u64> for Simple {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u64) -> Result<Self, Self::Error> {
|
||||
let mut mask: u64 = 0o7777 << 52;
|
||||
let major = (value & mask) >> 52;
|
||||
mask = 0o37777;
|
||||
let p = u16::try_from(value & mask)?;
|
||||
let pre: PreRelease = p.try_into()?;
|
||||
Ok(Self {
|
||||
major: major.try_into()?,
|
||||
pre,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Simple {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.major == other.major && self.pre == other.pre
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Simple {}
|
||||
|
||||
impl Ord for Simple {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
let a = u64::from(*self);
|
||||
let b = u64::from(*other);
|
||||
a.cmp(&b)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Simple {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user