diff --git a/src/error.rs b/src/error.rs index fd08412..1024f82 100644 --- a/src/error.rs +++ b/src/error.rs @@ -8,6 +8,7 @@ pub enum Error { FromUint, Range, ParseInt, + ParseGitRev, ParsePreRelease, ParseSemver, TryFromInt, @@ -32,3 +33,9 @@ impl From for Error { Self::ParseInt } } + +impl From for Error { + fn from(_value: chrono::ParseError) -> Self { + Self::ParseGitRev + } +} diff --git a/src/extended.rs b/src/extended.rs index 63fcf6e..b72b303 100644 --- a/src/extended.rs +++ b/src/extended.rs @@ -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 for Extended { + fn from(value: Simple) -> Self { + Self { + major: value.major, + minor: 0, + patch: 0, + build: 0, + pre: value.pre, + } + } +} + +impl From for Extended { + fn from(value: Rapid) -> Self { + Self { + major: value.major, + minor: value.minor, + patch: 0, + build: 0, + pre: value.pre, + } + } +} + +impl From for Extended { + fn from(value: SemVer) -> Self { + Self { + major: value.major, + minor: value.minor, + patch: value.patch, + build: 0, + pre: value.pre, + } + } +} + +impl PartialEq 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 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 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 for Extended { + fn partial_cmp(&self, other: &SemVer) -> Option { + Some(u64::from(*self).cmp(&u64::from(*other))) + } +} + +impl PartialOrd for Extended { + fn partial_cmp(&self, other: &Rapid) -> Option { + Some(u64::from(*self).cmp(&u64::from(*other))) + } +} + +impl PartialOrd for Extended { + fn partial_cmp(&self, other: &Simple) -> Option { + Some(u64::from(*self).cmp(&u64::from(*other))) + } +} diff --git a/src/gitrev.rs b/src/gitrev.rs index e69de29..54f34fa 100644 --- a/src/gitrev.rs +++ b/src/gitrev.rs @@ -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, +} + +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 { + 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 { + 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 for GitRev { + type Error = ParseGitRevError; + + fn try_from(value: Version) -> Result { + 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); + } +} diff --git a/src/lib.rs b/src/lib.rs index 66249d0..2100744 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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), +}