diff --git a/src/version/mod.rs b/src/version/mod.rs index d6c048f..d37217b 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -1,21 +1,26 @@ use { chrono::{offset::Utc, DateTime}, serde::{Deserialize, Serialize}, - std::{error::Error, fmt, str::FromStr}, + std::{cmp::Ordering, error::Error, fmt, str::FromStr}, }; mod gitrev; +mod rapid; mod semver; -pub use {gitrev::GitRev, semver::SemVer}; +pub use {gitrev::GitRev, rapid::Rapid, semver::SemVer}; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub enum Version { Number(u32), + Rapid { + major: u32, + minor: u32, + }, SemVer { - major: u8, - minor: u8, - patch: u8, + major: u32, + minor: u32, + patch: u32, }, Git { hash: String, @@ -49,6 +54,13 @@ impl fmt::Display for Version { }; write!(f, "{v}") } + Self::Rapid { major, minor } => { + let v = Rapid { + major: *major, + minor: *minor, + }; + write!(f, "{v}") + } Self::Git { hash, datetime } => { let v = GitRev { hash: hash.clone(), @@ -70,6 +82,15 @@ impl From for Version { } } +impl From for Version { + fn from(value: Rapid) -> Self { + Self::Rapid { + major: value.major, + minor: value.minor, + } + } +} + impl From for Version { fn from(value: GitRev) -> Self { Self::Git { @@ -91,27 +112,35 @@ impl PartialOrd for Version { match (self, other) { (Self::Number(s), Self::Number(o)) => s.partial_cmp(o), ( + Self::SemVer { + major, + minor, + patch, + }, Self::SemVer { major: a, minor: b, patch: c, }, - Self::SemVer { - major: d, - minor: e, - patch: f, - }, - ) => (a, b, c).partial_cmp(&(d, e, f)), + ) => (major, minor, patch).partial_cmp(&(a, b, c)), + (Self::Rapid { major, minor }, Self::Rapid { major: a, minor: b }) => { + (major, minor).partial_cmp(&(a, b)) + } ( Self::Git { - hash: a, + hash: _a, datetime: b, }, Self::Git { - hash: c, + hash: _c, datetime: d, }, - ) => (a, b).partial_cmp(&(c, d)), + ) => b.partial_cmp(&d), + ( + Self::SemVer { major, minor, patch }, + Self::Rapid { major: a, minor: b }, + ) => SemVer { major: *major, minor: *minor, patch: *patch } + .partial_cmp(&Rapid { major: *a, minor: *b }), _ => None, } } @@ -134,6 +163,8 @@ impl FromStr for Version { fn from_str(s: &str) -> Result { if let Ok(v) = s.parse::() { Ok(v.into()) + } else if let Ok(v) = s.parse::() { + Ok(v.into()) } else if let Ok(v) = s.parse::() { Ok(v.into()) } else if let Ok(v) = s.parse::() { @@ -143,3 +174,28 @@ impl FromStr for Version { } } } + +impl PartialEq for SemVer { + fn eq(&self, other: &Rapid) -> bool { + self.major == other.major && self.minor == other.minor && self.patch == 0 + } +} + +impl PartialOrd for SemVer { + fn partial_cmp(&self, other: &Rapid) -> Option { + match self.major.partial_cmp(&other.major) { + Some(Ordering::Greater) => Some(Ordering::Greater), + Some(Ordering::Less) => Some(Ordering::Less), + None => None, + Some(Ordering::Equal) => match self.minor.partial_cmp(&other.minor) { + Some(Ordering::Greater) => Some(Ordering::Greater), + Some(Ordering::Less) => Some(Ordering::Less), + None => None, + Some(Ordering::Equal) => match self.patch { + 0 => Some(Ordering::Equal), + _ => Some(Ordering::Greater), + }, + }, + } + } +} diff --git a/src/version/rapid.rs b/src/version/rapid.rs new file mode 100644 index 0000000..53a667e --- /dev/null +++ b/src/version/rapid.rs @@ -0,0 +1,86 @@ +use { + serde::{Deserialize, Serialize}, + std::{cmp::Ordering, error::Error, fmt, num::ParseIntError, str::FromStr}, +}; + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +pub struct Rapid { + pub major: u32, + pub minor: u32, +} + +impl fmt::Display for Rapid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}.{}", self.major, self.minor) + } +} + +impl PartialOrd for Rapid { + fn partial_cmp(&self, other: &Self) -> Option { + match self.major.partial_cmp(&other.major) { + Some(Ordering::Greater) => Some(Ordering::Greater), + Some(Ordering::Less) => Some(Ordering::Less), + Some(Ordering::Equal) => self.minor.partial_cmp(&other.minor), + None => None, + } + } +} + +impl Ord for Rapid { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match self.major.cmp(&other.major) { + Ordering::Greater => Ordering::Greater, + Ordering::Less => Ordering::Less, + Ordering::Equal => self.minor.cmp(&other.minor), + } + } +} + +#[derive(Debug, PartialEq)] +pub struct ParseRapidError; + +impl fmt::Display for ParseRapidError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Error parsing Rapid version") + } +} + +impl Error for ParseRapidError {} + +impl From for ParseRapidError { + fn from(_value: ParseIntError) -> Self { + Self + } +} + +impl FromStr for Rapid { + type Err = ParseRapidError; + + fn from_str(s: &str) -> Result { + let split = s.split('.').collect::>(); + match split.len() { + 2 => { + let major = split.first().unwrap().parse::()?; + let minor = split.get(1).unwrap().parse::()?; + Ok(Self { major, minor }) + } + _ => Err(ParseRapidError), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn parse_semver() { + assert_eq!( + "93.0".parse::(), + Ok(Rapid { + major: 93, + minor: 0, + }) + ); + } +} diff --git a/src/version/semver.rs b/src/version/semver.rs index 474bb31..e4dbc35 100644 --- a/src/version/semver.rs +++ b/src/version/semver.rs @@ -5,9 +5,9 @@ use { #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct SemVer { - pub major: u8, - pub minor: u8, - pub patch: u8, + pub major: u32, + pub minor: u32, + pub patch: u32, } impl fmt::Display for SemVer { @@ -70,9 +70,9 @@ impl FromStr for SemVer { let split = s.split('.').collect::>(); match split.len() { 3 => { - let major = split.first().unwrap().parse::()?; - let minor = split.get(1).unwrap().parse::()?; - let patch = split.get(2).unwrap().parse::()?; + let major = split.first().unwrap().parse::()?; + let minor = split.get(1).unwrap().parse::()?; + let patch = split.get(2).unwrap().parse::()?; Ok(Self { major, minor,