-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
more pep440 impl; remove manifest in favor of function param
- Loading branch information
Showing
9 changed files
with
236 additions
and
733 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod pep440; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use std::cmp::Ordering; | ||
use std::fmt; | ||
use regex::Regex; | ||
|
||
#[derive(Debug, Copy, Clone)] | ||
pub struct PEP440String<'a> { | ||
pre: i16, | ||
alpha: &'a str, | ||
post: i16, | ||
} | ||
|
||
impl<'a> PEP440String<'a> { | ||
fn new(input: &'a str) -> PEP440String { | ||
lazy_static! { | ||
static ref RE: Regex = Regex::new(r"^(\d*)([a-zA-Z]*)(\d*)").unwrap(); | ||
} | ||
|
||
let caps = RE.captures(input).unwrap(); | ||
let pre: i16 = caps.get(1).map_or(0, |m| m.as_str().parse().unwrap()); | ||
let alpha = caps.get(2).map_or("", |m| m.as_str()); | ||
let post: i16 = caps.get(3).map_or(0, |m| m.as_str().parse().unwrap()); | ||
|
||
PEP440String{pre, alpha, post } | ||
} | ||
|
||
pub fn empty() -> PEP440String<'a> { | ||
PEP440String {pre: 0, alpha: "", post: 0} | ||
} | ||
} | ||
|
||
fn compare_pep440_str<'a>(left: &'a str, right: &'a str) -> Option<Ordering> { | ||
lazy_static! { static ref DEV_RE: Regex = Regex::new("dev").unwrap(); } | ||
lazy_static! { static ref POST_RE: Regex = Regex::new("post").unwrap(); } | ||
|
||
let is_dev = (DEV_RE.is_match(left), DEV_RE.is_match(right)); | ||
let is_post = (POST_RE.is_match(left), POST_RE.is_match(right)); | ||
|
||
let str_match = left.partial_cmp(right); | ||
match str_match { | ||
Some(Ordering::Equal) => Some(Ordering::Equal), | ||
_ => match is_dev { | ||
(false, true) => Some(Ordering::Greater), | ||
(true, false) => Some(Ordering::Less), | ||
_ => match is_post { | ||
(true, true) => Some(Ordering::Equal), | ||
(false, true) => Some(Ordering::Less), | ||
(true, false) => Some(Ordering::Greater), | ||
// this is the final fallback to lexicographic sorting, if neither | ||
// dev nor post are in effect | ||
(false, false) => left.partial_cmp(right), | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl<'a> PartialOrd for PEP440String<'a> { | ||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
match self.pre.partial_cmp(&other.pre) { | ||
Some(Ordering::Greater) => Some(Ordering::Greater), | ||
Some(Ordering::Less) => Some(Ordering::Less), | ||
Some(Ordering::Equal) => match compare_pep440_str(self.alpha, &other.alpha) { | ||
Some(Ordering::Equal) => self.post.partial_cmp(&other.post), | ||
Some(Ordering::Greater) => Some(Ordering::Greater), | ||
Some(Ordering::Less) => Some(Ordering::Less), | ||
_ => panic!() | ||
} | ||
_ => panic!() | ||
} | ||
} | ||
} | ||
|
||
impl<'a> PartialEq for PEP440String<'a> { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.partial_cmp(&other).unwrap() == Ordering::Equal | ||
} | ||
} | ||
|
||
impl<'a> fmt::Display for PEP440String<'a> { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "{}{}{}", self.pre, self.alpha, self.post) | ||
} | ||
} | ||
|
||
#[cfg_attr(tarpaulin, skip)] | ||
#[cfg(test)] | ||
mod tests { | ||
use super::PEP440String; | ||
|
||
#[test] | ||
fn compare_implict_leading_zero() { | ||
assert_eq!(PEP440String::new("0dev"), PEP440String::new("dev")); | ||
// epoch of any value trumps integer (priority) | ||
// assert!(VersionPart::Epoch(value: 0) > VersionPart::Integer(value: 1); | ||
// assert!(Version::Epoch{0} > Version::String{"abc"}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use crate::version_part::VersionPart; | ||
|
||
/// Split the given version string, in it's version parts. | ||
/// TODO: Move this method to some sort of helper class, maybe as part of `VersionPart`. | ||
pub fn default_parser( | ||
version: &str, | ||
) -> Option<Vec<VersionPart>> { | ||
// Split the version string, and create a vector to put the parts in | ||
// TODO: split at specific separators instead | ||
let split = version.split(|c| !char::is_alphanumeric(c)); | ||
let mut parts = Vec::new(); | ||
|
||
// Flag to determine whether this version number contains any number part | ||
let mut has_number = false; | ||
|
||
// Loop over the parts, and parse them | ||
for part in split { | ||
// Skip empty parts | ||
if part.is_empty() { | ||
continue; | ||
} | ||
|
||
// Try to parse the value as an number | ||
match part.parse::<i32>() { | ||
Ok(number) => { | ||
// Push the number part to the vector, and set the has number flag | ||
parts.push(VersionPart::Integer(number)); | ||
has_number = true; | ||
} | ||
Err(_) => { | ||
// Push the text part to the vector | ||
parts.push(VersionPart::LexicographicString(part)); | ||
} | ||
} | ||
} | ||
|
||
// The version must contain a number part, if any part was parsed | ||
if !has_number && !parts.is_empty() { | ||
return None; | ||
} | ||
|
||
// Return the list of parts | ||
Some(parts) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod conda; | ||
pub mod default; |
Oops, something went wrong.