aboutsummaryrefslogtreecommitdiff
path: root/semver-parser/src/range.rs
diff options
context:
space:
mode:
Diffstat (limited to 'semver-parser/src/range.rs')
-rw-r--r--semver-parser/src/range.rs696
1 files changed, 0 insertions, 696 deletions
diff --git a/semver-parser/src/range.rs b/semver-parser/src/range.rs
deleted file mode 100644
index 858be9f..0000000
--- a/semver-parser/src/range.rs
+++ /dev/null
@@ -1,696 +0,0 @@
-use common::{self, numeric_identifier, letters_numbers_dash_dot};
-use version::Identifier;
-use std::str::{FromStr, from_utf8};
-use recognize::*;
-
-#[derive(Debug)]
-pub struct VersionReq {
- pub predicates: Vec<Predicate>,
-}
-
-#[derive(PartialEq,Debug)]
-pub enum WildcardVersion {
- Major,
- Minor,
- Patch,
-}
-
-#[derive(PartialEq,Debug)]
-pub enum Op {
- Ex, // Exact
- Gt, // Greater than
- GtEq, // Greater than or equal to
- Lt, // Less than
- LtEq, // Less than or equal to
- Tilde, // e.g. ~1.0.0
- Compatible, // compatible by definition of semver, indicated by ^
- Wildcard(WildcardVersion), // x.y.*, x.*, *
-}
-
-impl FromStr for Op {
- type Err = String;
-
- fn from_str(s: &str) -> Result<Op, String> {
- match s {
- "=" => Ok(Op::Ex),
- ">" => Ok(Op::Gt),
- ">=" => Ok(Op::GtEq),
- "<" => Ok(Op::Lt),
- "<=" => Ok(Op::LtEq),
- "~" => Ok(Op::Tilde),
- "^" => Ok(Op::Compatible),
- _ => Err(String::from("Could not parse Op")),
- }
- }
-}
-
-#[derive(PartialEq,Debug)]
-pub struct Predicate {
- pub op: Op,
- pub major: u64,
- pub minor: Option<u64>,
- pub patch: Option<u64>,
- pub pre: Vec<Identifier>,
-}
-
-fn numeric_or_wild(s: &[u8]) -> Option<(Option<u64>, usize)> {
- if let Some((val, len)) = numeric_identifier(s) {
- Some((Some(val), len))
- } else if let Some(len) = OneOf(b"*xX").p(s) {
- Some((None, len))
- } else {
- None
- }
-}
-
-fn dot_numeric_or_wild(s: &[u8]) -> Option<(Option<u64>, usize)> {
- b'.'.p(s).and_then(|len|
- numeric_or_wild(&s[len..]).map(|(val, len2)| (val, len + len2))
- )
-}
-
-fn operation(s: &[u8]) -> Option<(Op, usize)> {
- if let Some(len) = "=".p(s) {
- Some((Op::Ex, len))
- } else if let Some(len) = ">=".p(s) {
- Some((Op::GtEq, len))
- } else if let Some(len) = ">".p(s) {
- Some((Op::Gt, len))
- } else if let Some(len) = "<=".p(s) {
- Some((Op::LtEq, len))
- } else if let Some(len) = "<".p(s) {
- Some((Op::Lt, len))
- } else if let Some(len) = "~".p(s) {
- Some((Op::Tilde, len))
- } else if let Some(len) = "^".p(s) {
- Some((Op::Compatible, len))
- } else {
- None
- }
-}
-
-fn whitespace(s: &[u8]) -> Option<usize> {
- ZeroOrMore(OneOf(b"\t\r\n ")).p(s)
-}
-
-pub fn parse_predicate(range: &str) -> Result<Predicate, String> {
- let s = range.trim().as_bytes();
- let mut i = 0;
- let mut operation = if let Some((op, len)) = operation(&s[i..]) {
- i += len;
- op
- } else {
- // operations default to Compatible
- Op::Compatible
- };
- if let Some(len) = whitespace.p(&s[i..]) {
- i += len;
- }
- let major = if let Some((major, len)) = numeric_identifier(&s[i..]) {
- i += len;
- major
- } else {
- return Err("Error parsing major version number: ".to_string());
- };
- let minor = if let Some((minor, len)) = dot_numeric_or_wild(&s[i..]) {
- i += len;
- if minor.is_none() {
- operation = Op::Wildcard(WildcardVersion::Minor);
- }
- minor
- } else {
- None
- };
- let patch = if let Some((patch, len)) = dot_numeric_or_wild(&s[i..]) {
- i += len;
- if patch.is_none() {
- operation = Op::Wildcard(WildcardVersion::Patch);
- }
- patch
- } else {
- None
- };
- let (pre, pre_len) = common::parse_optional_meta(&s[i..], b'-')?;
- i += pre_len;
- if let Some(len) = (b'+', letters_numbers_dash_dot).p(&s[i..]) {
- i += len;
- }
- if i != s.len() {
- return Err("Extra junk after valid predicate: ".to_string() +
- from_utf8(&s[i..]).unwrap());
- }
- Ok(Predicate {
- op: operation,
- major: major,
- minor: minor,
- patch: patch,
- pre: pre,
- })
-}
-
-pub fn parse(ranges: &str) -> Result<VersionReq, String> {
- // null is an error
- if ranges == "\0" {
- return Err(String::from("Null is not a valid VersionReq"));
- }
-
- // an empty range is a major version wildcard
- // so is a lone * or x of either capitalization
- if (ranges == "")
- || (ranges == "*")
- || (ranges == "x")
- || (ranges == "X") {
- return Ok(VersionReq {
- predicates: vec![Predicate {
- op: Op::Wildcard(WildcardVersion::Major),
- major: 0,
- minor: None,
- patch: None,
- pre: Vec::new(),
- }],
- });
- }
-
-
- let ranges = ranges.trim();
-
- let predicates: Result<Vec<_>, String> = ranges
- .split(",")
- .map(|range| {
- parse_predicate(range)
- })
- .collect();
-
- let predicates = try!(predicates);
-
- if predicates.len() == 0 {
- return Err(String::from("VersionReq did not parse properly"));
- }
-
- Ok(VersionReq {
- predicates: predicates,
- })
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use range;
- use version::Identifier;
-
- #[test]
- fn test_parsing_default() {
- let r = range::parse("1.0.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Compatible,
- major: 1,
- minor: Some(0),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_exact_01() {
- let r = range::parse("=1.0.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Ex,
- major: 1,
- minor: Some(0),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_exact_02() {
- let r = range::parse("=0.9.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Ex,
- major: 0,
- minor: Some(9),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_exact_03() {
- let r = range::parse("=0.1.0-beta2.a").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Ex,
- major: 0,
- minor: Some(1),
- patch: Some(0),
- pre: vec![Identifier::AlphaNumeric(String::from("beta2")),
- Identifier::AlphaNumeric(String::from("a"))],
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_parsing_greater_than() {
- let r = range::parse("> 1.0.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Gt,
- major: 1,
- minor: Some(0),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_parsing_greater_than_01() {
- let r = range::parse(">= 1.0.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::GtEq,
- major: 1,
- minor: Some(0),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_parsing_greater_than_02() {
- let r = range::parse(">= 2.1.0-alpha2").unwrap();
-
- assert_eq!(Predicate {
- op: Op::GtEq,
- major: 2,
- minor: Some(1),
- patch: Some(0),
- pre: vec![Identifier::AlphaNumeric(String::from("alpha2"))],
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_parsing_less_than() {
- let r = range::parse("< 1.0.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Lt,
- major: 1,
- minor: Some(0),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_parsing_less_than_eq() {
- let r = range::parse("<= 2.1.0-alpha2").unwrap();
-
- assert_eq!(Predicate {
- op: Op::LtEq,
- major: 2,
- minor: Some(1),
- patch: Some(0),
- pre: vec![Identifier::AlphaNumeric(String::from("alpha2"))],
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_parsing_tilde() {
- let r = range::parse("~1").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Tilde,
- major: 1,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_parsing_compatible() {
- let r = range::parse("^0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Compatible,
- major: 0,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_blank() {
- let r = range::parse("").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Major),
- major: 0,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_wildcard() {
- let r = range::parse("*").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Major),
- major: 0,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_x() {
- let r = range::parse("x").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Major),
- major: 0,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_capital_x() {
- let r = range::parse("X").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Major),
- major: 0,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_minor_wildcard_star() {
- let r = range::parse("1.*").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Minor),
- major: 1,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_minor_wildcard_x() {
- let r = range::parse("1.x").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Minor),
- major: 1,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_minor_wildcard_capital_x() {
- let r = range::parse("1.X").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Minor),
- major: 1,
- minor: None,
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_patch_wildcard_star() {
- let r = range::parse("1.2.*").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Patch),
- major: 1,
- minor: Some(2),
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_patch_wildcard_x() {
- let r = range::parse("1.2.x").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Patch),
- major: 1,
- minor: Some(2),
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- fn test_parsing_patch_wildcard_capital_x() {
- let r = range::parse("1.2.X").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Wildcard(WildcardVersion::Patch),
- major: 1,
- minor: Some(2),
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[0]
- );
- }
-
- #[test]
- pub fn test_multiple_01() {
- let r = range::parse("> 0.0.9, <= 2.5.3").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Gt,
- major: 0,
- minor: Some(0),
- patch: Some(9),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
-
- assert_eq!(Predicate {
- op: Op::LtEq,
- major: 2,
- minor: Some(5),
- patch: Some(3),
- pre: Vec::new(),
- },
- r.predicates[1]
- );
- }
-
- #[test]
- pub fn test_multiple_02() {
- let r = range::parse("0.3.0, 0.4.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Compatible,
- major: 0,
- minor: Some(3),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
-
- assert_eq!(Predicate {
- op: Op::Compatible,
- major: 0,
- minor: Some(4),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[1]
- );
- }
-
- #[test]
- pub fn test_multiple_03() {
- let r = range::parse("<= 0.2.0, >= 0.5.0").unwrap();
-
- assert_eq!(Predicate {
- op: Op::LtEq,
- major: 0,
- minor: Some(2),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
-
- assert_eq!(Predicate {
- op: Op::GtEq,
- major: 0,
- minor: Some(5),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[1]
- );
- }
-
- #[test]
- pub fn test_multiple_04() {
- let r = range::parse("0.1.0, 0.1.4, 0.1.6").unwrap();
-
- assert_eq!(Predicate {
- op: Op::Compatible,
- major: 0,
- minor: Some(1),
- patch: Some(0),
- pre: Vec::new(),
- },
- r.predicates[0]
- );
-
- assert_eq!(Predicate {
- op: Op::Compatible,
- major: 0,
- minor: Some(1),
- patch: Some(4),
- pre: Vec::new(),
- },
- r.predicates[1]
- );
-
- assert_eq!(Predicate {
- op: Op::Compatible,
- major: 0,
- minor: Some(1),
- patch: Some(6),
- pre: Vec::new(),
- },
- r.predicates[2]
- );
- }
-
- #[test]
- pub fn test_multiple_05() {
- let r = range::parse(">=0.5.1-alpha3, <0.6").unwrap();
-
- assert_eq!(Predicate {
- op: Op::GtEq,
- major: 0,
- minor: Some(5),
- patch: Some(1),
- pre: vec![Identifier::AlphaNumeric(String::from("alpha3"))],
- },
- r.predicates[0]
- );
-
- assert_eq!(Predicate {
- op: Op::Lt,
- major: 0,
- minor: Some(6),
- patch: None,
- pre: Vec::new(),
- },
- r.predicates[1]
- );
- }
-
- #[test]
- fn test_parse_build_metadata_with_predicate() {
- assert_eq!(range::parse("^1.2.3+meta").unwrap().predicates[0].op,
- Op::Compatible);
- assert_eq!(range::parse("~1.2.3+meta").unwrap().predicates[0].op,
- Op::Tilde);
- assert_eq!(range::parse("=1.2.3+meta").unwrap().predicates[0].op,
- Op::Ex);
- assert_eq!(range::parse("<=1.2.3+meta").unwrap().predicates[0].op,
- Op::LtEq);
- assert_eq!(range::parse(">=1.2.3+meta").unwrap().predicates[0].op,
- Op::GtEq);
- assert_eq!(range::parse("<1.2.3+meta").unwrap().predicates[0].op,
- Op::Lt);
- assert_eq!(range::parse(">1.2.3+meta").unwrap().predicates[0].op,
- Op::Gt);
- }
-
- #[test]
- pub fn test_parse_errors() {
- assert!(range::parse("\0").is_err());
- assert!(range::parse(">= >= 0.0.2").is_err());
- assert!(range::parse(">== 0.0.2").is_err());
- assert!(range::parse("a.0.0").is_err());
- assert!(range::parse("1.0.0-").is_err());
- assert!(range::parse(">=").is_err());
- assert!(range::parse("> 0.1.0,").is_err());
- assert!(range::parse("> 0.3.0, ,").is_err());
- }
-
- #[test]
- pub fn test_large_major_version() {
- assert!(range::parse("18446744073709551617.0.0").is_err());
- }
-
- #[test]
- pub fn test_large_minor_version() {
- assert!(range::parse("0.18446744073709551617.0").is_err());
- }
-
- #[test]
- pub fn test_large_patch_version() {
- assert!(range::parse("0.0.18446744073709551617").is_err());
- }
-}