Add `Extended` to version enum

This commit is contained in:
Nathan Fisher 2023-07-08 18:40:06 -04:00
parent 6ca276c125
commit 3e65c13a5b
5 changed files with 231 additions and 7 deletions

View File

@ -178,15 +178,15 @@ fn init(matches: &ArgMatches) -> Result<PathBuf, Box<dyn Error>> {
}
fn search(_matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
unimplemented!();
todo!();
}
fn remove(_matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
unimplemented!();
todo!();
}
fn upgrade() -> Result<(), Box<dyn Error>> {
unimplemented!();
todo!();
}
#[allow(clippy::cast_possible_truncation)]

157
src/version/extended.rs Normal file
View File

@ -0,0 +1,157 @@
use {
super::{Rapid, SemVer, Version},
serde::{Deserialize, Serialize},
std::{cmp::Ordering, error::Error, fmt, num::ParseIntError, str::FromStr},
};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Extended {
pub major: u32,
pub minor: u32,
pub patch: u32,
pub ext: u32,
}
impl fmt::Display for Extended {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}.{}.{}.{}",
self.major, self.minor, self.patch, self.ext
)
}
}
impl PartialOrd for Extended {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
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.partial_cmp(&other.patch) {
Some(Ordering::Greater) => Some(Ordering::Greater),
Some(Ordering::Less) => Some(Ordering::Less),
None => None,
Some(Ordering::Equal) => self.ext.partial_cmp(&other.ext),
},
},
}
}
}
impl Ord for Extended {
fn cmp(&self, other: &Self) -> Ordering {
match self.major.cmp(&other.major) {
Ordering::Greater => Ordering::Greater,
Ordering::Less => Ordering::Less,
Ordering::Equal => match self.minor.cmp(&other.minor) {
Ordering::Greater => Ordering::Greater,
Ordering::Less => Ordering::Less,
Ordering::Equal => match self.patch.cmp(&other.patch) {
Ordering::Greater => Ordering::Greater,
Ordering::Less => Ordering::Less,
Ordering::Equal => self.ext.cmp(&other.ext),
},
},
}
}
}
impl PartialEq<SemVer> for Extended {
fn eq(&self, other: &SemVer) -> bool {
self.major == other.major
&& self.minor == other.minor
&& self.patch == other.patch
&& self.ext == 0
}
}
impl PartialOrd<SemVer> for Extended {
fn partial_cmp(&self, other: &SemVer) -> Option<Ordering> {
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.partial_cmp(&other.patch) {
Some(Ordering::Greater) => Some(Ordering::Greater),
Some(Ordering::Less) => Some(Ordering::Less),
None => None,
Some(Ordering::Equal) => match self.ext {
0 => Some(Ordering::Equal),
_ => Some(Ordering::Greater),
},
},
},
}
}
}
impl PartialEq<Rapid> for Extended {
fn eq(&self, other: &Rapid) -> bool {
self.major == other.major && self.minor == other.minor && self.patch == 0 && self.ext == 0
}
}
impl PartialOrd<Rapid> for Extended {
fn partial_cmp(&self, other: &Rapid) -> Option<Ordering> {
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, self.ext) {
(0, 0) => Some(Ordering::Equal),
_ => Some(Ordering::Greater),
},
},
}
}
}
impl PartialEq<u32> for Extended {
fn eq(&self, other: &u32) -> bool {
self.major == *other && self.minor == 0 && self.patch == 0 && self.ext == 0
}
}
impl PartialOrd<u32> for Extended {
fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
match self.major.partial_cmp(other) {
Some(Ordering::Greater) => Some(Ordering::Greater),
Some(Ordering::Less) => Some(Ordering::Less),
None => None,
_ => match (self.minor, self.patch, self.ext) {
(0, 0, 0) => Some(Ordering::Equal),
_ => Some(Ordering::Greater),
},
}
}
}
impl PartialEq<Extended> for u32 {
fn eq(&self, other: &Extended) -> bool {
*self == other.major && other.minor == 0 && other.patch == 0 && other.ext == 0
}
}
impl PartialOrd<Extended> for u32 {
fn partial_cmp(&self, other: &Extended) -> Option<Ordering> {
match other.partial_cmp(self) {
Some(Ordering::Less) => Some(Ordering::Greater),
Some(Ordering::Greater) => Some(Ordering::Less),
Some(Ordering::Equal) => Some(Ordering::Equal),
None => None,
}
}
}

View File

@ -3,11 +3,12 @@ use {
std::{error::Error, fmt, str::FromStr},
};
mod extended;
mod gitrev;
mod rapid;
mod semver;
pub use {gitrev::GitRev, rapid::Rapid, semver::SemVer};
pub use {extended::Extended, gitrev::GitRev, rapid::Rapid, semver::SemVer};
#[derive(Clone, Debug, Serialize, Deserialize)]
/// An enum representing the most common versioning schemes.
@ -25,6 +26,9 @@ pub enum Version {
/// of three dot (.) separated numbers. The numbers are major,
/// minor, and patch respctively.
SemVer(SemVer),
/// The Extended versioning scheme adds one more number beyond
/// the patch number
Extended(Extended),
/// A git revision. Use of this scheme is to be avoided in
/// official packaging as it cannot be readily compared with
/// other versioning schemes for dependency resolution.
@ -44,6 +48,7 @@ impl Default for Version {
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Extended(e) => write!(f, "{e}"),
Self::Number(n) => write!(f, "{n}"),
Self::SemVer(s) => write!(f, "{s}"),
Self::Rapid(r) => write!(f, "{r}"),
@ -52,6 +57,12 @@ impl fmt::Display for Version {
}
}
impl From<Extended> for Version {
fn from(value: Extended) -> Self {
Self::Extended(value)
}
}
impl From<SemVer> for Version {
fn from(value: SemVer) -> Self {
Self::SemVer(value)
@ -83,12 +94,18 @@ impl PartialOrd for Version {
(Self::Number(s), Self::Number(o)) => s.partial_cmp(o),
(Self::Number(s), Self::Rapid(o)) => s.partial_cmp(o),
(Self::Number(s), Self::SemVer(o)) => s.partial_cmp(o),
(Self::Number(s), Self::Extended(o)) => s.partial_cmp(o),
(Self::Rapid(s), Self::Number(o)) => s.partial_cmp(o),
(Self::Rapid(s), Self::Rapid(o)) => s.partial_cmp(o),
(Self::Rapid(s), Self::SemVer(o)) => s.partial_cmp(o),
(Self::Rapid(s), Self::Extended(o)) => s.partial_cmp(o),
(Self::SemVer(s), Self::Number(o)) => s.partial_cmp(o),
(Self::SemVer(s), Self::Rapid(o)) => s.partial_cmp(o),
(Self::SemVer(s), Self::SemVer(o)) => s.partial_cmp(o),
(Self::SemVer(s), Self::Extended(o)) => s.partial_cmp(o),
(Self::Extended(s), Self::Number(o)) => s.partial_cmp(o),
(Self::Extended(s), Self::Rapid(o)) => s.partial_cmp(o),
(Self::Extended(s), Self::SemVer(o)) => s.partial_cmp(o),
(Self::Git(s), Self::Git(o)) => s.partial_cmp(o),
_ => None,
}

View File

@ -1,5 +1,7 @@
use crate::SemVer;
use super::Extended;
use {
crate::Version,
serde::{Deserialize, Serialize},
@ -79,6 +81,23 @@ impl PartialOrd<SemVer> for Rapid {
}
}
impl PartialEq<Extended> for Rapid {
fn eq(&self, other: &Extended) -> bool {
other.eq(self)
}
}
impl PartialOrd<Extended> for Rapid {
fn partial_cmp(&self, other: &Extended) -> Option<Ordering> {
match other.partial_cmp(self) {
Some(Ordering::Less) => Some(Ordering::Greater),
Some(Ordering::Greater) => Some(Ordering::Less),
Some(Ordering::Equal) => Some(Ordering::Equal),
None => None,
}
}
}
impl PartialEq<Rapid> for u32 {
fn eq(&self, other: &Rapid) -> bool {
other.eq(self)
@ -134,6 +153,10 @@ impl TryFrom<Version> for Rapid {
fn try_from(value: Version) -> Result<Self, Self::Error> {
match value {
Version::Extended(ex) if ex.ext == 0 && ex.patch == 0 => Ok(Self {
major: ex.major,
minor: ex.minor,
}),
Version::SemVer(s) => {
if s.patch == 0 {
Ok(Self {
@ -146,7 +169,7 @@ impl TryFrom<Version> for Rapid {
}
Version::Rapid(s) => Ok(s),
Version::Number(major) => Ok(Self { major, minor: 0 }),
Version::Git(_) => Err(ParseRapidError),
_ => Err(ParseRapidError),
}
}
}

View File

@ -1,5 +1,7 @@
use super::Extended;
use {
crate::{Rapid, Version},
super::{Rapid, Version},
serde::{Deserialize, Serialize},
std::{cmp::Ordering, error::Error, fmt, num::ParseIntError, str::FromStr},
};
@ -72,6 +74,26 @@ impl PartialOrd<Rapid> for SemVer {
}
}
impl PartialEq<Extended> for SemVer {
fn eq(&self, other: &Extended) -> bool {
self.major == other.major
&& self.minor == other.minor
&& self.patch == other.patch
&& other.ext == 0
}
}
impl PartialOrd<Extended> for SemVer {
fn partial_cmp(&self, other: &Extended) -> Option<Ordering> {
match other.partial_cmp(self) {
Some(Ordering::Less) => Some(Ordering::Greater),
Some(Ordering::Greater) => Some(Ordering::Less),
Some(Ordering::Equal) => Some(Ordering::Equal),
None => None,
}
}
}
impl PartialEq<u32> for SemVer {
fn eq(&self, other: &u32) -> bool {
self.major == *other && self.minor == 0 && self.patch == 0
@ -153,6 +175,11 @@ impl TryFrom<Version> for SemVer {
type Error = ParseSemVerError;
fn try_from(value: Version) -> Result<Self, Self::Error> {
match value {
Version::Extended(ex) if ex.ext == 0 => Ok(SemVer {
major: ex.major,
minor: ex.minor,
patch: ex.patch,
}),
Version::SemVer(s) => Ok(SemVer {
major: s.major,
minor: s.minor,
@ -168,7 +195,7 @@ impl TryFrom<Version> for SemVer {
minor: 0,
patch: 0,
}),
Version::Git(_) => Err(ParseSemVerError),
_ => Err(ParseSemVerError),
}
}
}