145 lines
3.5 KiB
Rust
145 lines
3.5 KiB
Rust
use {
|
|
crate::{
|
|
error::Error, extended::Extended, gitrev::GitRev, prerelease::PreRelease, rapid::Rapid,
|
|
semver::SemVer, 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))
|
|
}
|
|
}
|
|
|
|
impl PartialEq<Extended> for Simple {
|
|
fn eq(&self, other: &Extended) -> bool {
|
|
self.major == other.major
|
|
&& other.minor == 0
|
|
&& other.patch == 0
|
|
&& other.build == 0
|
|
&& self.pre == other.pre
|
|
}
|
|
}
|
|
|
|
impl PartialEq<SemVer> for Simple {
|
|
fn eq(&self, other: &SemVer) -> bool {
|
|
self.major == other.major && other.minor == 0 && other.patch == 0 && self.pre == other.pre
|
|
}
|
|
}
|
|
|
|
impl PartialEq<Rapid> for Simple {
|
|
fn eq(&self, other: &Rapid) -> bool {
|
|
self.major == other.major && other.minor == 0 && self.pre == other.pre
|
|
}
|
|
}
|
|
|
|
impl PartialEq<GitRev> for Simple {
|
|
fn eq(&self, _other: &GitRev) -> bool {
|
|
false
|
|
}
|
|
}
|
|
|
|
impl PartialOrd<Extended> for Simple {
|
|
fn partial_cmp(&self, other: &Extended) -> Option<Ordering> {
|
|
let a = u64::from(*self);
|
|
let b = u64::from(*other);
|
|
Some(a.cmp(&b))
|
|
}
|
|
}
|
|
|
|
impl PartialOrd<SemVer> for Simple {
|
|
fn partial_cmp(&self, other: &SemVer) -> Option<Ordering> {
|
|
let a = u64::from(*self);
|
|
let b = u64::from(*other);
|
|
Some(a.cmp(&b))
|
|
}
|
|
}
|
|
|
|
impl PartialOrd<Rapid> for Simple {
|
|
fn partial_cmp(&self, other: &Rapid) -> Option<Ordering> {
|
|
let a = u64::from(*self);
|
|
let b = u64::from(*other);
|
|
Some(a.cmp(&b))
|
|
}
|
|
}
|
|
|
|
impl PartialOrd<GitRev> for Simple {
|
|
fn partial_cmp(&self, _other: &GitRev) -> Option<Ordering> {
|
|
None
|
|
}
|
|
}
|