Add GitRev struct and Version enum; Begin impl PartialOrd where LHS type doesn't match RHS type

This commit is contained in:
Nathan Fisher 2024-01-08 00:46:21 -05:00
parent 88de80e0d3
commit 298185d8d4
4 changed files with 188 additions and 3 deletions

View File

@ -8,6 +8,7 @@ pub enum Error {
FromUint,
Range,
ParseInt,
ParseGitRev,
ParsePreRelease,
ParseSemver,
TryFromInt,
@ -32,3 +33,9 @@ impl From<ParseIntError> for Error {
Self::ParseInt
}
}
impl From<chrono::ParseError> for Error {
fn from(_value: chrono::ParseError) -> Self {
Self::ParseGitRev
}
}

View File

@ -1,5 +1,5 @@
use {
crate::{Error, PreRelease, MAX_U12},
crate::{Error, PreRelease, Rapid, SemVer, Simple, MAX_U12},
serde::{Deserialize, Serialize},
std::{cmp::Ordering, fmt, str::FromStr},
};
@ -119,3 +119,87 @@ impl PartialOrd for Extended {
Some(self.cmp(other))
}
}
impl From<Simple> for Extended {
fn from(value: Simple) -> Self {
Self {
major: value.major,
minor: 0,
patch: 0,
build: 0,
pre: value.pre,
}
}
}
impl From<Rapid> for Extended {
fn from(value: Rapid) -> Self {
Self {
major: value.major,
minor: value.minor,
patch: 0,
build: 0,
pre: value.pre,
}
}
}
impl From<SemVer> for Extended {
fn from(value: SemVer) -> Self {
Self {
major: value.major,
minor: value.minor,
patch: value.patch,
build: 0,
pre: value.pre,
}
}
}
impl PartialEq<SemVer> for Extended {
fn eq(&self, other: &SemVer) -> bool {
self.major == other.major
&& self.minor == other.minor
&& self.patch == other.patch
&& self.build == 0
&& self.pre == other.pre
}
}
impl PartialEq<Rapid> for Extended {
fn eq(&self, other: &Rapid) -> bool {
self.major == other.major
&& self.minor == other.minor
&& self.patch == 0
&& self.build == 0
&& self.pre == other.pre
}
}
impl PartialEq<Simple> for Extended {
fn eq(&self, other: &Simple) -> bool {
self.major == other.major
&& self.minor == 0
&& self.patch == 0
&& self.build == 0
&& self.pre == other.pre
}
}
impl PartialOrd<SemVer> for Extended {
fn partial_cmp(&self, other: &SemVer) -> Option<Ordering> {
Some(u64::from(*self).cmp(&u64::from(*other)))
}
}
impl PartialOrd<Rapid> for Extended {
fn partial_cmp(&self, other: &Rapid) -> Option<Ordering> {
Some(u64::from(*self).cmp(&u64::from(*other)))
}
}
impl PartialOrd<Simple> for Extended {
fn partial_cmp(&self, other: &Simple) -> Option<Ordering> {
Some(u64::from(*self).cmp(&u64::from(*other)))
}
}

View File

@ -0,0 +1,84 @@
use {
crate::Error,
chrono::{offset::Utc, DateTime},
serde::{Deserialize, Serialize},
std::{cmp::Ordering, fmt, str::FromStr},
};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
/// Represents a Git revision
pub struct GitRev {
/// the short revision hash
pub hash: String,
/// the time of the revision commit
pub datetime: DateTime<Utc>,
}
impl fmt::Display for GitRev {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "git_{}.{}", self.hash, self.datetime.format("%Y%m%d"))
}
}
impl PartialOrd for GitRev {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.datetime.partial_cmp(&other.datetime)
}
}
impl Ord for GitRev {
fn cmp(&self, other: &Self) -> Ordering {
self.datetime.cmp(&other.datetime)
}
}
impl FromStr for GitRev {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(gitrev) = s.strip_prefix("git_") {
if let Some((hash, date)) = gitrev.split_once('_') {
if hash.len() == 7 {
let datetime = DateTime::parse_from_str(date, "%Y%m%d")?;
return Ok(Self {
hash: hash.to_string(),
datetime: datetime.into(),
});
}
}
}
Err(Error::ParseGitRev)
}
}
/*
impl TryFrom<Version> for GitRev {
type Error = ParseGitRevError;
fn try_from(value: Version) -> Result<Self, Self::Error> {
match value {
Version::Git(g) => Ok(g),
_ => Err(ParseGitRevError),
}
}
}*/
#[cfg(test)]
mod test {
use std::{thread, time::Duration};
use super::*;
#[test]
fn ord() {
let a = GitRev {
hash: "aaab".to_string(),
datetime: Utc::now(),
};
thread::sleep(Duration::from_millis(10));
let b = GitRev {
hash: "aaaa".to_string(),
datetime: Utc::now(),
};
assert!(a < b);
}
}

View File

@ -1,13 +1,23 @@
mod error;
mod extended;
mod gitrev;
mod prerelease;
mod rapid;
mod semver;
mod simple;
pub use {
error::Error, extended::Extended, prerelease::PreRelease, rapid::Rapid, semver::SemVer,
simple::Simple,
error::Error, extended::Extended, gitrev::GitRev, prerelease::PreRelease, rapid::Rapid,
semver::SemVer, simple::Simple,
};
pub static MAX_U12: u16 = 4096;
#[derive(Clone, Debug)]
pub enum Version {
Simple(Simple),
Rapid(Rapid),
SemVer(SemVer),
Extended(Extended),
GitRev(GitRev),
}