diff options
Diffstat (limited to 'semver/src')
| -rw-r--r-- | semver/src/lib.rs | 182 | ||||
| -rw-r--r-- | semver/src/version.rs | 759 | ||||
| -rw-r--r-- | semver/src/version_req.rs | 895 | 
3 files changed, 0 insertions, 1836 deletions
| diff --git a/semver/src/lib.rs b/semver/src/lib.rs deleted file mode 100644 index a38aae0..0000000 --- a/semver/src/lib.rs +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Semantic version parsing and comparison. -//! -//! Semantic versioning (see http://semver.org/) is a set of rules for -//! assigning version numbers. -//! -//! ## SemVer overview -//! -//! Given a version number MAJOR.MINOR.PATCH, increment the: -//! -//! 1. MAJOR version when you make incompatible API changes, -//! 2. MINOR version when you add functionality in a backwards-compatible -//!    manner, and -//! 3. PATCH version when you make backwards-compatible bug fixes. -//! -//! Additional labels for pre-release and build metadata are available as -//! extensions to the MAJOR.MINOR.PATCH format. -//! -//! Any references to 'the spec' in this documentation refer to [version 2.0 of -//! the SemVer spec](http://semver.org/spec/v2.0.0.html). -//! -//! ## SemVer and the Rust ecosystem -//! -//! Rust itself follows the SemVer specification, as does its standard -//! libraries. The two are not tied together. -//! -//! [Cargo](http://crates.io), Rust's package manager, uses SemVer to determine -//! which versions of packages you need installed. -//! -//! ## Versions -//! -//! At its simplest, the `semver` crate allows you to construct `Version` -//! objects using the `parse` method: -//! -//! ```{rust} -//! use semver::Version; -//! -//! assert!(Version::parse("1.2.3") == Ok(Version { -//!    major: 1, -//!    minor: 2, -//!    patch: 3, -//!    pre: vec!(), -//!    build: vec!(), -//! })); -//! ``` -//! -//! If you have multiple `Version`s, you can use the usual comparison operators -//! to compare them: -//! -//! ```{rust} -//! use semver::Version; -//! -//! assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta")); -//! assert!(Version::parse("1.2.3-alpha2") >  Version::parse("1.2.0")); -//! ``` -//! -//! If you explicitly need to modify a Version, SemVer also allows you to -//! increment the major, minor, and patch numbers in accordance with the spec. -//! -//! Please note that in order to do this, you must use a mutable Version: -//! -//! ```{rust} -//! use semver::Version; -//! -//! let mut bugfix_release = Version::parse("1.0.0").unwrap(); -//! bugfix_release.increment_patch(); -//! -//! assert_eq!(Ok(bugfix_release), Version::parse("1.0.1")); -//! ``` -//! -//! When incrementing the minor version number, the patch number resets to zero -//! (in accordance with section 7 of the spec) -//! -//! ```{rust} -//! use semver::Version; -//! -//! let mut feature_release = Version::parse("1.4.6").unwrap(); -//! feature_release.increment_minor(); -//! -//! assert_eq!(Ok(feature_release), Version::parse("1.5.0")); -//! ``` -//! -//! Similarly, when incrementing the major version number, the patch and minor -//! numbers reset to zero (in accordance with section 8 of the spec) -//! -//! ```{rust} -//! use semver::Version; -//! -//! let mut chrome_release = Version::parse("41.5.5377").unwrap(); -//! chrome_release.increment_major(); -//! -//! assert_eq!(Ok(chrome_release), Version::parse("42.0.0")); -//! ``` -//! -//! ## Requirements -//! -//! The `semver` crate also provides the ability to compare requirements, which -//! are more complex comparisons. -//! -//! For example, creating a requirement that only matches versions greater than -//! or equal to 1.0.0: -//! -//! ```{rust} -//! # #![allow(unstable)] -//! use semver::Version; -//! use semver::VersionReq; -//! -//! let r = VersionReq::parse(">= 1.0.0").unwrap(); -//! let v = Version::parse("1.0.0").unwrap(); -//! -//! assert!(r.to_string() == ">= 1.0.0".to_string()); -//! assert!(r.matches(&v)) -//! ``` -//! -//! It also allows parsing of `~x.y.z` and `^x.y.z` requirements as defined at -//! https://www.npmjs.org/doc/misc/semver.html -//! -//! **Tilde requirements** specify a minimal version with some updates: -//! -//! ```notrust -//! ~1.2.3 := >=1.2.3 <1.3.0 -//! ~1.2   := >=1.2.0 <1.3.0 -//! ~1     := >=1.0.0 <2.0.0 -//! ``` -//! -//! **Caret requirements** allow SemVer compatible updates to a specified -//! verion, `0.x` and `0.x+1` are not considered compatible, but `1.x` and -//! `1.x+1` are. -//! -//! `0.0.x` is not considered compatible with any other version. -//! Missing minor and patch versions are desugared to `0` but allow flexibility -//! for that value. -//! -//! ```notrust -//! ^1.2.3 := >=1.2.3 <2.0.0 -//! ^0.2.3 := >=0.2.3 <0.3.0 -//! ^0.0.3 := >=0.0.3 <0.0.4 -//! ^0.0   := >=0.0.0 <0.1.0 -//! ^0     := >=0.0.0 <1.0.0 -//! ``` -//! -//! **Wildcard requirements** allows parsing of version requirements of the -//! formats `*`, `x.*` and `x.y.*`. -//! -//! ```notrust -//! *     := >=0.0.0 -//! 1.*   := >=1.0.0 <2.0.0 -//! 1.2.* := >=1.2.0 <1.3.0 -//! ``` - -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", -       html_favicon_url = "https://www.rust-lang.org/favicon.ico")] -#![deny(missing_docs)] -#![cfg_attr(test, deny(warnings))] - -extern crate semver_parser; - -// Serialization and deserialization support for version numbers -#[cfg(feature = "serde")] -extern crate serde; - -// We take the common approach of keeping our own module system private, and -// just re-exporting the interface that we want. - -pub use version::{Version, Identifier, SemVerError}; -pub use version::Identifier::{Numeric, AlphaNumeric}; -pub use version_req::{VersionReq, ReqParseError}; - -// SemVer-compliant versions. -mod version; - -// advanced version comparisons -mod version_req; diff --git a/semver/src/version.rs b/semver/src/version.rs deleted file mode 100644 index 38de133..0000000 --- a/semver/src/version.rs +++ /dev/null @@ -1,759 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! The `version` module gives you tools to create and compare SemVer-compliant -//! versions. - -use std::cmp::{self, Ordering}; -use std::fmt; -use std::hash; -use std::error::Error; - -use std::result; -use std::str; - -use semver_parser; - -#[cfg(feature = "serde")] -use serde::ser::{Serialize, Serializer}; -#[cfg(feature = "serde")] -use serde::de::{self, Deserialize, Deserializer, Visitor}; - -/// An identifier in the pre-release or build metadata. -/// -/// See sections 9 and 10 of the spec for more about pre-release identifers and -/// build metadata. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub enum Identifier { -    /// An identifier that's solely numbers. -    Numeric(u64), -    /// An identifier with letters and numbers. -    AlphaNumeric(String), -} - -impl From<semver_parser::version::Identifier> for Identifier { -    fn from(other: semver_parser::version::Identifier) -> Identifier { -        match other { -            semver_parser::version::Identifier::Numeric(n) => Identifier::Numeric(n), -            semver_parser::version::Identifier::AlphaNumeric(s) => Identifier::AlphaNumeric(s), -        } -    } -} - -impl fmt::Display for Identifier { -    #[inline] -    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -        match *self { -            Identifier::Numeric(ref n) => fmt::Display::fmt(n, f), -            Identifier::AlphaNumeric(ref s) => fmt::Display::fmt(s, f), -        } -    } -} - -#[cfg(feature = "serde")] -impl Serialize for Identifier { -    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error> -        where S: Serializer -    { -        // Serialize Identifier as a number or string. -        match *self { -            Identifier::Numeric(n) => serializer.serialize_u64(n), -            Identifier::AlphaNumeric(ref s) => serializer.serialize_str(s), -        } -    } -} - -#[cfg(feature = "serde")] -impl<'de> Deserialize<'de> for Identifier { -    fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error> -        where D: Deserializer<'de> -    { -        struct IdentifierVisitor; - -        // Deserialize Identifier from a number or string. -        impl<'de> Visitor<'de> for IdentifierVisitor { -            type Value = Identifier; - -            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { -                formatter.write_str("a SemVer pre-release or build identifier") -            } - -            fn visit_u64<E>(self, numeric: u64) -> result::Result<Self::Value, E> -                where E: de::Error -            { -                Ok(Identifier::Numeric(numeric)) -            } - -            fn visit_str<E>(self, alphanumeric: &str) -> result::Result<Self::Value, E> -                where E: de::Error -            { -                Ok(Identifier::AlphaNumeric(alphanumeric.to_owned())) -            } -        } - -        deserializer.deserialize_any(IdentifierVisitor) -    } -} - -/// Represents a version number conforming to the semantic versioning scheme. -#[derive(Clone, Eq, Debug)] -pub struct Version { -    /// The major version, to be incremented on incompatible changes. -    pub major: u64, -    /// The minor version, to be incremented when functionality is added in a -    /// backwards-compatible manner. -    pub minor: u64, -    /// The patch version, to be incremented when backwards-compatible bug -    /// fixes are made. -    pub patch: u64, -    /// The pre-release version identifier, if one exists. -    pub pre: Vec<Identifier>, -    /// The build metadata, ignored when determining version precedence. -    pub build: Vec<Identifier>, -} - -impl From<semver_parser::version::Version> for Version { -    fn from(other: semver_parser::version::Version) -> Version { -        Version { -            major: other.major, -            minor: other.minor, -            patch: other.patch, -            pre: other.pre.into_iter().map(From::from).collect(), -            build: other.build.into_iter().map(From::from).collect(), -        } -    } -} - -#[cfg(feature = "serde")] -impl Serialize for Version { -    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error> -        where S: Serializer -    { -        // Serialize Version as a string. -        serializer.collect_str(self) -    } -} - -#[cfg(feature = "serde")] -impl<'de> Deserialize<'de> for Version { -    fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error> -        where D: Deserializer<'de> -    { -        struct VersionVisitor; - -        // Deserialize Version from a string. -        impl<'de> Visitor<'de> for VersionVisitor { -            type Value = Version; - -            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { -                formatter.write_str("a SemVer version as a string") -            } - -            fn visit_str<E>(self, v: &str) -> result::Result<Self::Value, E> -                where E: de::Error -            { -                Version::parse(v).map_err(de::Error::custom) -            } -        } - -        deserializer.deserialize_str(VersionVisitor) -    } -} - -/// An error type for this crate -/// -/// Currently, just a generic error. Will make this nicer later. -#[derive(Clone,PartialEq,Debug,PartialOrd)] -pub enum SemVerError { -    /// An error ocurred while parsing. -    ParseError(String), -} - -impl fmt::Display for SemVerError { -    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -        match self { -            &SemVerError::ParseError(ref m) => write!(f, "{}", m), -        } -    } -} - -impl Error for SemVerError { -    fn description(&self) -> &str { -        match self { -            &SemVerError::ParseError(ref m) => m, -        } -    } -} - -/// A Result type for errors -pub type Result<T> = result::Result<T, SemVerError>; - -impl Version { - -    /// Contructs the simple case without pre or build. -    pub fn new(major: u64, minor: u64, patch: u64) -> Version { -        Version { -            major: major, -            minor: minor, -            patch: patch, -            pre: Vec::new(), -            build: Vec::new() -        } -    } - -    /// Parse a string into a semver object. -    pub fn parse(version: &str) -> Result<Version> { -        let res = semver_parser::version::parse(version); - -        match res { -            // Convert plain String error into proper ParseError -            Err(e) => Err(SemVerError::ParseError(e)), -            Ok(v) => Ok(From::from(v)), -        } -    } - -    /// Clears the build metadata -    fn clear_metadata(&mut self) { -        self.build = Vec::new(); -        self.pre = Vec::new(); -    } - -    /// Increments the patch number for this Version (Must be mutable) -    pub fn increment_patch(&mut self) { -        self.patch += 1; -        self.clear_metadata(); -    } - -    /// Increments the minor version number for this Version (Must be mutable) -    /// -    /// As instructed by section 7 of the spec, the patch number is reset to 0. -    pub fn increment_minor(&mut self) { -        self.minor += 1; -        self.patch = 0; -        self.clear_metadata(); -    } - -    /// Increments the major version number for this Version (Must be mutable) -    /// -    /// As instructed by section 8 of the spec, the minor and patch numbers are -    /// reset to 0 -    pub fn increment_major(&mut self) { -        self.major += 1; -        self.minor = 0; -        self.patch = 0; -        self.clear_metadata(); -    } - -    /// Checks to see if the current Version is in pre-release status -    pub fn is_prerelease(&self) -> bool { -        !self.pre.is_empty() -    } -} - -impl str::FromStr for Version { -    type Err = SemVerError; - -    fn from_str(s: &str) -> Result<Version> { -        Version::parse(s) -    } -} - -impl fmt::Display for Version { -    #[inline] -    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -        try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch)); -        if !self.pre.is_empty() { -            try!(write!(f, "-")); -            for (i, x) in self.pre.iter().enumerate() { -                if i != 0 { -                    try!(write!(f, ".")) -                } -                try!(write!(f, "{}", x)); -            } -        } -        if !self.build.is_empty() { -            try!(write!(f, "+")); -            for (i, x) in self.build.iter().enumerate() { -                if i != 0 { -                    try!(write!(f, ".")) -                } -                try!(write!(f, "{}", x)); -            } -        } -        Ok(()) -    } -} - -impl cmp::PartialEq for Version { -    #[inline] -    fn eq(&self, other: &Version) -> bool { -        // We should ignore build metadata here, otherwise versions v1 and v2 -        // can exist such that !(v1 < v2) && !(v1 > v2) && v1 != v2, which -        // violate strict total ordering rules. -        self.major == other.major && self.minor == other.minor && self.patch == other.patch && -        self.pre == other.pre -    } -} - -impl cmp::PartialOrd for Version { -    fn partial_cmp(&self, other: &Version) -> Option<Ordering> { -        Some(self.cmp(other)) -    } -} - -impl cmp::Ord for Version { -    fn cmp(&self, other: &Version) -> Ordering { -        match self.major.cmp(&other.major) { -            Ordering::Equal => {} -            r => return r, -        } - -        match self.minor.cmp(&other.minor) { -            Ordering::Equal => {} -            r => return r, -        } - -        match self.patch.cmp(&other.patch) { -            Ordering::Equal => {} -            r => return r, -        } - -        // NB: semver spec says 0.0.0-pre < 0.0.0 -        // but the version of ord defined for vec -        // says that [] < [pre] so we alter it here -        match (self.pre.len(), other.pre.len()) { -            (0, 0) => Ordering::Equal, -            (0, _) => Ordering::Greater, -            (_, 0) => Ordering::Less, -            (_, _) => self.pre.cmp(&other.pre), -        } -    } -} - -impl hash::Hash for Version { -    fn hash<H: hash::Hasher>(&self, into: &mut H) { -        self.major.hash(into); -        self.minor.hash(into); -        self.patch.hash(into); -        self.pre.hash(into); -    } -} - -impl From<(u64,u64,u64)> for Version { -    fn from(tuple: (u64,u64,u64)) -> Version { -        let (major, minor, patch) = tuple; -        Version::new(major, minor, patch) -    } -} - -#[cfg(test)] -mod tests { -    use std::result; -    use super::Version; -    use super::Identifier; -    use super::SemVerError; - -    #[test] -    fn test_parse() { -        fn parse_error(e: &str) -> result::Result<Version, SemVerError> { -            return Err(SemVerError::ParseError(e.to_string())); -        } - -        assert_eq!(Version::parse(""), -                   parse_error("Error parsing major identifier")); -        assert_eq!(Version::parse("  "), -                   parse_error("Error parsing major identifier")); -        assert_eq!(Version::parse("1"), -                   parse_error("Expected dot")); -        assert_eq!(Version::parse("1.2"), -                   parse_error("Expected dot")); -        assert_eq!(Version::parse("1.2.3-"), -                   parse_error("Error parsing prerelease")); -        assert_eq!(Version::parse("a.b.c"), -                   parse_error("Error parsing major identifier")); -        assert_eq!(Version::parse("1.2.3 abc"), -                   parse_error("Extra junk after valid version:  abc")); - -        assert_eq!(Version::parse("1.2.3"), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: Vec::new(), -                   })); - -        assert_eq!(Version::parse("1.2.3"), -                   Ok(Version::new(1,2,3))); - -        assert_eq!(Version::parse("  1.2.3  "), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: Vec::new(), -                   })); -        assert_eq!(Version::parse("1.2.3-alpha1"), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: Vec::new(), -                   })); -        assert_eq!(Version::parse("  1.2.3-alpha1  "), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: Vec::new(), -                   })); -        assert_eq!(Version::parse("1.2.3+build5"), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!(Version::parse("  1.2.3+build5  "), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!(Version::parse("1.2.3-alpha1+build5"), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!(Version::parse("  1.2.3-alpha1+build5  "), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!(Version::parse("1.2.3-1.alpha1.9+build5.7.3aedf  "), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::Numeric(1), -                      Identifier::AlphaNumeric(String::from("alpha1")), -                      Identifier::Numeric(9), -            ], -                       build: vec![Identifier::AlphaNumeric(String::from("build5")), -                        Identifier::Numeric(7), -                        Identifier::AlphaNumeric(String::from("3aedf")), -            ], -                   })); -        assert_eq!(Version::parse("0.4.0-beta.1+0851523"), -                   Ok(Version { -                       major: 0, -                       minor: 4, -                       patch: 0, -                       pre: vec![Identifier::AlphaNumeric(String::from("beta")), -                      Identifier::Numeric(1), -            ], -                       build: vec![Identifier::AlphaNumeric(String::from("0851523"))], -                   })); - -    } - -    #[test] -    fn test_increment_patch() { -        let mut buggy_release = Version::parse("0.1.0").unwrap(); -        buggy_release.increment_patch(); -        assert_eq!(buggy_release, Version::parse("0.1.1").unwrap()); -    } - -    #[test] -    fn test_increment_minor() { -        let mut feature_release = Version::parse("1.4.6").unwrap(); -        feature_release.increment_minor(); -        assert_eq!(feature_release, Version::parse("1.5.0").unwrap()); -    } - -    #[test] -    fn test_increment_major() { -        let mut chrome_release = Version::parse("46.1.246773").unwrap(); -        chrome_release.increment_major(); -        assert_eq!(chrome_release, Version::parse("47.0.0").unwrap()); -    } - -    #[test] -    fn test_increment_keep_prerelease() { -        let mut release = Version::parse("1.0.0-alpha").unwrap(); -        release.increment_patch(); - -        assert_eq!(release, Version::parse("1.0.1").unwrap()); - -        release.increment_minor(); - -        assert_eq!(release, Version::parse("1.1.0").unwrap()); - -        release.increment_major(); - -        assert_eq!(release, Version::parse("2.0.0").unwrap()); -    } - - -    #[test] -    fn test_increment_clear_metadata() { -        let mut release = Version::parse("1.0.0+4442").unwrap(); -        release.increment_patch(); - -        assert_eq!(release, Version::parse("1.0.1").unwrap()); -        release = Version::parse("1.0.1+hello").unwrap(); - -        release.increment_minor(); - -        assert_eq!(release, Version::parse("1.1.0").unwrap()); -        release = Version::parse("1.1.3747+hello").unwrap(); - -        release.increment_major(); - -        assert_eq!(release, Version::parse("2.0.0").unwrap()); -    } - -    #[test] -    fn test_eq() { -        assert_eq!(Version::parse("1.2.3"), Version::parse("1.2.3")); -        assert_eq!(Version::parse("1.2.3-alpha1"), -                   Version::parse("1.2.3-alpha1")); -        assert_eq!(Version::parse("1.2.3+build.42"), -                   Version::parse("1.2.3+build.42")); -        assert_eq!(Version::parse("1.2.3-alpha1+42"), -                   Version::parse("1.2.3-alpha1+42")); -        assert_eq!(Version::parse("1.2.3+23"), Version::parse("1.2.3+42")); -    } - -    #[test] -    fn test_ne() { -        assert!(Version::parse("0.0.0") != Version::parse("0.0.1")); -        assert!(Version::parse("0.0.0") != Version::parse("0.1.0")); -        assert!(Version::parse("0.0.0") != Version::parse("1.0.0")); -        assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta")); -    } - -    #[test] -    fn test_show() { -        assert_eq!(format!("{}", Version::parse("1.2.3").unwrap()), -                   "1.2.3".to_string()); -        assert_eq!(format!("{}", Version::parse("1.2.3-alpha1").unwrap()), -                   "1.2.3-alpha1".to_string()); -        assert_eq!(format!("{}", Version::parse("1.2.3+build.42").unwrap()), -                   "1.2.3+build.42".to_string()); -        assert_eq!(format!("{}", Version::parse("1.2.3-alpha1+42").unwrap()), -                   "1.2.3-alpha1+42".to_string()); -    } - -    #[test] -    fn test_to_string() { -        assert_eq!(Version::parse("1.2.3").unwrap().to_string(), -                   "1.2.3".to_string()); -        assert_eq!(Version::parse("1.2.3-alpha1").unwrap().to_string(), -                   "1.2.3-alpha1".to_string()); -        assert_eq!(Version::parse("1.2.3+build.42").unwrap().to_string(), -                   "1.2.3+build.42".to_string()); -        assert_eq!(Version::parse("1.2.3-alpha1+42").unwrap().to_string(), -                   "1.2.3-alpha1+42".to_string()); -    } - -    #[test] -    fn test_lt() { -        assert!(Version::parse("0.0.0") < Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.0.0") < Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.2.0") < Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3")); -        assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3-alpha2")); -        assert!(!(Version::parse("1.2.3-alpha2") < Version::parse("1.2.3-alpha2"))); -        assert!(!(Version::parse("1.2.3+23") < Version::parse("1.2.3+42"))); -    } - -    #[test] -    fn test_le() { -        assert!(Version::parse("0.0.0") <= Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.0.0") <= Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.2.0") <= Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.2.3-alpha1") <= Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.2.3-alpha2") <= Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.2.3+23") <= Version::parse("1.2.3+42")); -    } - -    #[test] -    fn test_gt() { -        assert!(Version::parse("1.2.3-alpha2") > Version::parse("0.0.0")); -        assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.0.0")); -        assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.0")); -        assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha1")); -        assert!(Version::parse("1.2.3") > Version::parse("1.2.3-alpha2")); -        assert!(!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha2"))); -        assert!(!(Version::parse("1.2.3+23") > Version::parse("1.2.3+42"))); -    } - -    #[test] -    fn test_ge() { -        assert!(Version::parse("1.2.3-alpha2") >= Version::parse("0.0.0")); -        assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.0.0")); -        assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.0")); -        assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha1")); -        assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha2")); -        assert!(Version::parse("1.2.3+23") >= Version::parse("1.2.3+42")); -    } - -    #[test] -    fn test_prerelease_check() { -        assert!(Version::parse("1.0.0").unwrap().is_prerelease() == false); -        assert!(Version::parse("0.0.1").unwrap().is_prerelease() == false); -        assert!(Version::parse("4.1.4-alpha").unwrap().is_prerelease()); -        assert!(Version::parse("1.0.0-beta294296").unwrap().is_prerelease()); -    } - -    #[test] -    fn test_spec_order() { -        let vs = ["1.0.0-alpha", -                  "1.0.0-alpha.1", -                  "1.0.0-alpha.beta", -                  "1.0.0-beta", -                  "1.0.0-beta.2", -                  "1.0.0-beta.11", -                  "1.0.0-rc.1", -                  "1.0.0"]; -        let mut i = 1; -        while i < vs.len() { -            let a = Version::parse(vs[i - 1]); -            let b = Version::parse(vs[i]); -            assert!(a < b, "nope {:?} < {:?}", a, b); -            i += 1; -        } -    } - -    #[test] -    fn test_from_str() { -        assert_eq!("1.2.3".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: Vec::new(), -                   })); -        assert_eq!("  1.2.3  ".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: Vec::new(), -                   })); -        assert_eq!("1.2.3-alpha1".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: Vec::new(), -                   })); -        assert_eq!("  1.2.3-alpha1  ".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: Vec::new(), -                   })); -        assert_eq!("1.2.3+build5".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!("  1.2.3+build5  ".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: Vec::new(), -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!("1.2.3-alpha1+build5".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!("  1.2.3-alpha1+build5  ".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))], -                       build: vec![Identifier::AlphaNumeric(String::from("build5"))], -                   })); -        assert_eq!("1.2.3-1.alpha1.9+build5.7.3aedf  ".parse(), -                   Ok(Version { -                       major: 1, -                       minor: 2, -                       patch: 3, -                       pre: vec![Identifier::Numeric(1), -                      Identifier::AlphaNumeric(String::from("alpha1")), -                      Identifier::Numeric(9), -            ], -                       build: vec![Identifier::AlphaNumeric(String::from("build5")), -                        Identifier::Numeric(7), -                        Identifier::AlphaNumeric(String::from("3aedf")), -            ], -                   })); -        assert_eq!("0.4.0-beta.1+0851523".parse(), -                   Ok(Version { -                       major: 0, -                       minor: 4, -                       patch: 0, -                       pre: vec![Identifier::AlphaNumeric(String::from("beta")), -                      Identifier::Numeric(1), -            ], -                       build: vec![Identifier::AlphaNumeric(String::from("0851523"))], -                   })); - -    } - -    #[test] -    fn test_from_str_errors() { -        fn parse_error(e: &str) -> result::Result<Version, SemVerError> { -            return Err(SemVerError::ParseError(e.to_string())); -        } - -        assert_eq!("".parse(), parse_error("Error parsing major identifier")); -        assert_eq!("  ".parse(), parse_error("Error parsing major identifier")); -        assert_eq!("1".parse(), parse_error("Expected dot")); -        assert_eq!("1.2".parse(), -                   parse_error("Expected dot")); -        assert_eq!("1.2.3-".parse(), -                   parse_error("Error parsing prerelease")); -        assert_eq!("a.b.c".parse(), -                   parse_error("Error parsing major identifier")); -        assert_eq!("1.2.3 abc".parse(), -                   parse_error("Extra junk after valid version:  abc")); -    } -} diff --git a/semver/src/version_req.rs b/semver/src/version_req.rs deleted file mode 100644 index 6e6a542..0000000 --- a/semver/src/version_req.rs +++ /dev/null @@ -1,895 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::error::Error; -use std::fmt; -use std::result; -use std::str; - -use Version; -use version::Identifier; -use semver_parser; - -#[cfg(feature = "serde")] -use serde::ser::{Serialize, Serializer}; -#[cfg(feature = "serde")] -use serde::de::{self, Deserialize, Deserializer, Visitor}; - -use self::Op::{Ex, Gt, GtEq, Lt, LtEq, Tilde, Compatible, Wildcard}; -use self::WildcardVersion::{Major, Minor, Patch}; -use self::ReqParseError::*; - -/// A `VersionReq` is a struct containing a list of predicates that can apply to ranges of version -/// numbers. Matching operations can then be done with the `VersionReq` against a particular -/// version to see if it satisfies some or all of the constraints. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct VersionReq { -    predicates: Vec<Predicate>, -} - -impl From<semver_parser::range::VersionReq> for VersionReq { -    fn from(other: semver_parser::range::VersionReq) -> VersionReq { -        VersionReq { predicates: other.predicates.into_iter().map(From::from).collect() } -    } -} - -#[cfg(feature = "serde")] -impl Serialize for VersionReq { -    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error> -        where S: Serializer -    { -        // Serialize VersionReq as a string. -        serializer.collect_str(self) -    } -} - -#[cfg(feature = "serde")] -impl<'de> Deserialize<'de> for VersionReq { -    fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error> -        where D: Deserializer<'de> -    { -        struct VersionReqVisitor; - -        /// Deserialize `VersionReq` from a string. -        impl<'de> Visitor<'de> for VersionReqVisitor { -            type Value = VersionReq; - -            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { -                formatter.write_str("a SemVer version requirement as a string") -            } - -            fn visit_str<E>(self, v: &str) -> result::Result<Self::Value, E> -                where E: de::Error -            { -                VersionReq::parse(v).map_err(de::Error::custom) -            } -        } - -        deserializer.deserialize_str(VersionReqVisitor) -    } -} - -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -enum WildcardVersion { -    Major, -    Minor, -    Patch, -} - -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -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 From<semver_parser::range::Op> for Op { -    fn from(other: semver_parser::range::Op) -> Op { -        use semver_parser::range; -        match other { -            range::Op::Ex => Op::Ex, -            range::Op::Gt => Op::Gt, -            range::Op::GtEq => Op::GtEq, -            range::Op::Lt => Op::Lt, -            range::Op::LtEq => Op::LtEq, -            range::Op::Tilde => Op::Tilde, -            range::Op::Compatible => Op::Compatible, -            range::Op::Wildcard(version) => { -                match version { -                    range::WildcardVersion::Major => Op::Wildcard(WildcardVersion::Major), -                    range::WildcardVersion::Minor => Op::Wildcard(WildcardVersion::Minor), -                    range::WildcardVersion::Patch => Op::Wildcard(WildcardVersion::Patch), -                } -            } -        } -    } -} - -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -struct Predicate { -    op: Op, -    major: u64, -    minor: Option<u64>, -    patch: Option<u64>, -    pre: Vec<Identifier>, -} - -impl From<semver_parser::range::Predicate> for Predicate { -    fn from(other: semver_parser::range::Predicate) -> Predicate { -        Predicate { -            op: From::from(other.op), -            major: other.major, -            minor: other.minor, -            patch: other.patch, -            pre: other.pre.into_iter().map(From::from).collect(), -        } -    } -} - -/// A `ReqParseError` is returned from methods which parse a string into a `VersionReq`. Each -/// enumeration is one of the possible errors that can occur. -#[derive(Clone, Debug, PartialEq)] -pub enum ReqParseError { -    /// The given version requirement is invalid. -    InvalidVersionRequirement, -    /// You have already provided an operation, such as `=`, `~`, or `^`. Only use one. -    OpAlreadySet, -    /// The sigil you have written is not correct. -    InvalidSigil, -    /// All components of a version must be numeric. -    VersionComponentsMustBeNumeric, -    /// There was an error parsing an identifier. -    InvalidIdentifier, -    /// At least a major version is required. -    MajorVersionRequired, -    /// An unimplemented version requirement. -    UnimplementedVersionRequirement, -    /// This form of requirement is deprecated. -    DeprecatedVersionRequirement(VersionReq), -} - -impl fmt::Display for ReqParseError { -    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -        self.description().fmt(f) -    } -} - -impl Error for ReqParseError { -    fn description(&self) -> &str { -        match self { -            &InvalidVersionRequirement => "the given version requirement is invalid", -            &OpAlreadySet => { -                "you have already provided an operation, such as =, ~, or ^; only use one" -            }, -            &InvalidSigil => "the sigil you have written is not correct", -            &VersionComponentsMustBeNumeric => "version components must be numeric", -            &InvalidIdentifier => "invalid identifier", -            &MajorVersionRequired => "at least a major version number is required", -            &UnimplementedVersionRequirement => { -                "the given version requirement is not implemented, yet" -            }, -            &DeprecatedVersionRequirement(_) => "This requirement is deprecated", -        } -    } -} - -impl From<String> for ReqParseError { -    fn from(other: String) -> ReqParseError { -        match &*other { -            "Null is not a valid VersionReq" => ReqParseError::InvalidVersionRequirement, -            "VersionReq did not parse properly." => ReqParseError::OpAlreadySet, -            _ => ReqParseError::InvalidVersionRequirement, -        } -    } -} - -impl VersionReq { -    /// `any()` is a factory method which creates a `VersionReq` with no constraints. In other -    /// words, any version will match against it. -    /// -    /// # Examples -    /// -    /// ``` -    /// use semver::VersionReq; -    /// -    /// let anything = VersionReq::any(); -    /// ``` -    pub fn any() -> VersionReq { -        VersionReq { predicates: vec![] } -    } - -    /// `parse()` is the main constructor of a `VersionReq`. It takes a string like `"^1.2.3"` -    /// and turns it into a `VersionReq` that matches that particular constraint. -    /// -    /// A `Result` is returned which contains a `ReqParseError` if there was a problem parsing the -    /// `VersionReq`. -    /// -    /// # Examples -    /// -    /// ``` -    /// use semver::VersionReq; -    /// -    /// let version = VersionReq::parse("=1.2.3"); -    /// let version = VersionReq::parse(">1.2.3"); -    /// let version = VersionReq::parse("<1.2.3"); -    /// let version = VersionReq::parse("~1.2.3"); -    /// let version = VersionReq::parse("^1.2.3"); -    /// let version = VersionReq::parse("1.2.3"); // synonym for ^1.2.3 -    /// let version = VersionReq::parse("<=1.2.3"); -    /// let version = VersionReq::parse(">=1.2.3"); -    /// ``` -    /// -    /// This example demonstrates error handling, and will panic. -    /// -    /// ```should-panic -    /// use semver::VersionReq; -    /// -    /// let version = match VersionReq::parse("not a version") { -    ///     Ok(version) => version, -    ///     Err(e) => panic!("There was a problem parsing: {}", e), -    /// } -    /// ``` -    pub fn parse(input: &str) -> Result<VersionReq, ReqParseError> { -        let res = semver_parser::range::parse(input); - -        if let Ok(v) = res { -            return Ok(From::from(v)); -        } - -        return match VersionReq::parse_deprecated(input) { -            Some(v) => { -                Err(ReqParseError::DeprecatedVersionRequirement(v)) -            } -            None => Err(From::from(res.err().unwrap())), -        } -    } - -    fn parse_deprecated(version: &str) -> Option<VersionReq> { -        return match version { -            ".*" => Some(VersionReq::any()), -            "0.1.0." => Some(VersionReq::parse("0.1.0").unwrap()), -            "0.3.1.3" => Some(VersionReq::parse("0.3.13").unwrap()), -            "0.2*" => Some(VersionReq::parse("0.2.*").unwrap()), -            "*.0" => Some(VersionReq::any()), -            _ => None, -        } -    } - -    /// `exact()` is a factory method which creates a `VersionReq` with one exact constraint. -    /// -    /// # Examples -    /// -    /// ``` -    /// use semver::VersionReq; -    /// use semver::Version; -    /// -    /// let version = Version { major: 1, minor: 1, patch: 1, pre: vec![], build: vec![] }; -    /// let exact = VersionReq::exact(&version); -    /// ``` -    pub fn exact(version: &Version) -> VersionReq { -        VersionReq { predicates: vec![Predicate::exact(version)] } -    } - -    /// `matches()` matches a given `Version` against this `VersionReq`. -    /// -    /// # Examples -    /// -    /// ``` -    /// use semver::VersionReq; -    /// use semver::Version; -    /// -    /// let version = Version { major: 1, minor: 1, patch: 1, pre: vec![], build: vec![] }; -    /// let exact = VersionReq::exact(&version); -    /// -    /// assert!(exact.matches(&version)); -    /// ``` -    pub fn matches(&self, version: &Version) -> bool { -        // no predicates means anything matches -        if self.predicates.is_empty() { -            return true; -        } - -        self.predicates.iter().all(|p| p.matches(version)) && -        self.predicates.iter().any(|p| p.pre_tag_is_compatible(version)) -    } -} - -impl str::FromStr for VersionReq { -    type Err = ReqParseError; - -    fn from_str(s: &str) -> Result<VersionReq, ReqParseError> { -        VersionReq::parse(s) -    } -} - -impl Predicate { -    fn exact(version: &Version) -> Predicate { -        Predicate { -            op: Ex, -            major: version.major, -            minor: Some(version.minor), -            patch: Some(version.patch), -            pre: version.pre.clone(), -        } -    } - -    /// `matches()` takes a `Version` and determines if it matches this particular `Predicate`. -    pub fn matches(&self, ver: &Version) -> bool { -        match self.op { -            Ex => self.is_exact(ver), -            Gt => self.is_greater(ver), -            GtEq => self.is_exact(ver) || self.is_greater(ver), -            Lt => !self.is_exact(ver) && !self.is_greater(ver), -            LtEq => !self.is_greater(ver), -            Tilde => self.matches_tilde(ver), -            Compatible => self.is_compatible(ver), -            Wildcard(_) => self.matches_wildcard(ver), -        } -    } - -    fn is_exact(&self, ver: &Version) -> bool { -        if self.major != ver.major { -            return false; -        } - -        match self.minor { -            Some(minor) => { -                if minor != ver.minor { -                    return false; -                } -            } -            None => return true, -        } - -        match self.patch { -            Some(patch) => { -                if patch != ver.patch { -                    return false; -                } -            } -            None => return true, -        } - -        if self.pre != ver.pre { -            return false; -        } - -        true -    } - -    // https://docs.npmjs.com/misc/semver#prerelease-tags -    fn pre_tag_is_compatible(&self, ver: &Version) -> bool { -        // If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it will -        // only be -        // allowed to satisfy comparator sets if at least one comparator with the same -        // [major, -        // minor, patch] tuple also has a prerelease tag. -        !ver.is_prerelease() || -        (self.major == ver.major && self.minor == Some(ver.minor) && -         self.patch == Some(ver.patch) && !self.pre.is_empty()) -    } - -    fn is_greater(&self, ver: &Version) -> bool { -        if self.major != ver.major { -            return ver.major > self.major; -        } - -        match self.minor { -            Some(minor) => { -                if minor != ver.minor { -                    return ver.minor > minor; -                } -            } -            None => return false, -        } - -        match self.patch { -            Some(patch) => { -                if patch != ver.patch { -                    return ver.patch > patch; -                } -            } -            None => return false, -        } - -        if !self.pre.is_empty() { -            return ver.pre.is_empty() || ver.pre > self.pre; -        } - -        false -    } - -    // see https://www.npmjs.org/doc/misc/semver.html for behavior -    fn matches_tilde(&self, ver: &Version) -> bool { -        let minor = match self.minor { -            Some(n) => n, -            None => return self.major == ver.major, -        }; - -        match self.patch { -            Some(patch) => { -                self.major == ver.major && minor == ver.minor && -                (ver.patch > patch || (ver.patch == patch && self.pre_is_compatible(ver))) -            } -            None => self.major == ver.major && minor == ver.minor, -        } -    } - -    // see https://www.npmjs.org/doc/misc/semver.html for behavior -    fn is_compatible(&self, ver: &Version) -> bool { -        if self.major != ver.major { -            return false; -        } - -        let minor = match self.minor { -            Some(n) => n, -            None => return self.major == ver.major, -        }; - -        match self.patch { -            Some(patch) => { -                if self.major == 0 { -                    if minor == 0 { -                        ver.minor == minor && ver.patch == patch && self.pre_is_compatible(ver) -                    } else { -                        ver.minor == minor && -                        (ver.patch > patch || (ver.patch == patch && self.pre_is_compatible(ver))) -                    } -                } else { -                    ver.minor > minor || -                    (ver.minor == minor && -                     (ver.patch > patch || (ver.patch == patch && self.pre_is_compatible(ver)))) -                } -            } -            None => { -                if self.major == 0 { -                    ver.minor == minor -                } else { -                    ver.minor >= minor -                } -            } -        } -    } - -    fn pre_is_compatible(&self, ver: &Version) -> bool { -        ver.pre.is_empty() || ver.pre >= self.pre -    } - -    // see https://www.npmjs.org/doc/misc/semver.html for behavior -    fn matches_wildcard(&self, ver: &Version) -> bool { -        match self.op { -            Wildcard(Major) => true, -            Wildcard(Minor) => self.major == ver.major, -            Wildcard(Patch) => { -                match self.minor { -                    Some(minor) => self.major == ver.major && minor == ver.minor, -                    None => { -                        // minor and patch version astericks mean match on major -                        self.major == ver.major -                    } -                } -            } -            _ => false,  // unreachable -        } -    } -} - -impl fmt::Display for VersionReq { -    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { -        if self.predicates.is_empty() { -            try!(write!(fmt, "*")); -        } else { -            for (i, ref pred) in self.predicates.iter().enumerate() { -                if i == 0 { -                    try!(write!(fmt, "{}", pred)); -                } else { -                    try!(write!(fmt, ", {}", pred)); -                } -            } -        } - -        Ok(()) -    } -} - -impl fmt::Display for Predicate { -    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { -        match self.op { -            Wildcard(Major) => try!(write!(fmt, "*")), -            Wildcard(Minor) => try!(write!(fmt, "{}.*", self.major)), -            Wildcard(Patch) => { -                if let Some(minor) = self.minor { -                    try!(write!(fmt, "{}.{}.*", self.major, minor)) -                } else { -                    try!(write!(fmt, "{}.*.*", self.major)) -                } -            } -            _ => { -                try!(write!(fmt, "{}{}", self.op, self.major)); - -                match self.minor { -                    Some(v) => try!(write!(fmt, ".{}", v)), -                    None => (), -                } - -                match self.patch { -                    Some(v) => try!(write!(fmt, ".{}", v)), -                    None => (), -                } - -                if !self.pre.is_empty() { -                    try!(write!(fmt, "-")); -                    for (i, x) in self.pre.iter().enumerate() { -                        if i != 0 { -                            try!(write!(fmt, ".")) -                        } -                        try!(write!(fmt, "{}", x)); -                    } -                } -            } -        } - -        Ok(()) -    } -} - -impl fmt::Display for Op { -    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { -        match *self { -            Ex => try!(write!(fmt, "= ")), -            Gt => try!(write!(fmt, "> ")), -            GtEq => try!(write!(fmt, ">= ")), -            Lt => try!(write!(fmt, "< ")), -            LtEq => try!(write!(fmt, "<= ")), -            Tilde => try!(write!(fmt, "~")), -            Compatible => try!(write!(fmt, "^")), -            // gets handled specially in Predicate::fmt -            Wildcard(_) => try!(write!(fmt, "")), -        } -        Ok(()) -    } -} - -#[cfg(test)] -mod test { -    use super::{VersionReq, Op}; -    use super::super::version::Version; -    use std::hash::{Hash, Hasher}; - -    fn req(s: &str) -> VersionReq { -        VersionReq::parse(s).unwrap() -    } - -    fn version(s: &str) -> Version { -        match Version::parse(s) { -            Ok(v) => v, -            Err(e) => panic!("`{}` is not a valid version. Reason: {:?}", s, e), -        } -    } - -    fn assert_match(req: &VersionReq, vers: &[&str]) { -        for ver in vers.iter() { -            assert!(req.matches(&version(*ver)), "did not match {}", ver); -        } -    } - -    fn assert_not_match(req: &VersionReq, vers: &[&str]) { -        for ver in vers.iter() { -            assert!(!req.matches(&version(*ver)), "matched {}", ver); -        } -    } - -    fn calculate_hash<T: Hash>(t: T) -> u64 { -        use std::collections::hash_map::DefaultHasher; - -        let mut s = DefaultHasher::new(); -        t.hash(&mut s); -        s.finish() -    } - -    #[test] -    fn test_parsing_default() { -        let r = req("1.0.0"); - -        assert_eq!(r.to_string(), "^1.0.0".to_string()); - -        assert_match(&r, &["1.0.0", "1.0.1"]); -        assert_not_match(&r, &["0.9.9", "0.10.0", "0.1.0"]); -    } - -    #[test] -    fn test_parsing_exact() { -        let r = req("=1.0.0"); - -        assert!(r.to_string() == "= 1.0.0".to_string()); -        assert_eq!(r.to_string(), "= 1.0.0".to_string()); - -        assert_match(&r, &["1.0.0"]); -        assert_not_match(&r, &["1.0.1", "0.9.9", "0.10.0", "0.1.0", "1.0.0-pre"]); - -        let r = req("=0.9.0"); - -        assert_eq!(r.to_string(), "= 0.9.0".to_string()); - -        assert_match(&r, &["0.9.0"]); -        assert_not_match(&r, &["0.9.1", "1.9.0", "0.0.9"]); - -        let r = req("=0.1.0-beta2.a"); - -        assert_eq!(r.to_string(), "= 0.1.0-beta2.a".to_string()); - -        assert_match(&r, &["0.1.0-beta2.a"]); -        assert_not_match(&r, &["0.9.1", "0.1.0", "0.1.1-beta2.a", "0.1.0-beta2"]); -    } - -    #[test] -    fn test_parse_metadata_see_issue_88_see_issue_88() { -        for op in &[Op::Compatible, Op::Ex, Op::Gt, Op::GtEq, Op::Lt, Op::LtEq, Op::Tilde] { -            req(&format!("{} 1.2.3+meta", op)); -        } -    } - -    #[test] -    pub fn test_parsing_greater_than() { -        let r = req(">= 1.0.0"); - -        assert_eq!(r.to_string(), ">= 1.0.0".to_string()); - -        assert_match(&r, &["1.0.0", "2.0.0"]); -        assert_not_match(&r, &["0.1.0", "0.0.1", "1.0.0-pre", "2.0.0-pre"]); - -        let r = req(">= 2.1.0-alpha2"); - -        assert_match(&r, &["2.1.0-alpha2", "2.1.0-alpha3", "2.1.0", "3.0.0"]); -        assert_not_match(&r, -                         &["2.0.0", "2.1.0-alpha1", "2.0.0-alpha2", "3.0.0-alpha2"]); -    } - -    #[test] -    pub fn test_parsing_less_than() { -        let r = req("< 1.0.0"); - -        assert_eq!(r.to_string(), "< 1.0.0".to_string()); - -        assert_match(&r, &["0.1.0", "0.0.1"]); -        assert_not_match(&r, &["1.0.0", "1.0.0-beta", "1.0.1", "0.9.9-alpha"]); - -        let r = req("<= 2.1.0-alpha2"); - -        assert_match(&r, &["2.1.0-alpha2", "2.1.0-alpha1", "2.0.0", "1.0.0"]); -        assert_not_match(&r, -                         &["2.1.0", "2.2.0-alpha1", "2.0.0-alpha2", "1.0.0-alpha2"]); -    } - -    #[test] -    pub fn test_multiple() { -        let r = req("> 0.0.9, <= 2.5.3"); -        assert_eq!(r.to_string(), "> 0.0.9, <= 2.5.3".to_string()); -        assert_match(&r, &["0.0.10", "1.0.0", "2.5.3"]); -        assert_not_match(&r, &["0.0.8", "2.5.4"]); - -        let r = req("0.3.0, 0.4.0"); -        assert_eq!(r.to_string(), "^0.3.0, ^0.4.0".to_string()); -        assert_not_match(&r, &["0.0.8", "0.3.0", "0.4.0"]); - -        let r = req("<= 0.2.0, >= 0.5.0"); -        assert_eq!(r.to_string(), "<= 0.2.0, >= 0.5.0".to_string()); -        assert_not_match(&r, &["0.0.8", "0.3.0", "0.5.1"]); - -        let r = req("0.1.0, 0.1.4, 0.1.6"); -        assert_eq!(r.to_string(), "^0.1.0, ^0.1.4, ^0.1.6".to_string()); -        assert_match(&r, &["0.1.6", "0.1.9"]); -        assert_not_match(&r, &["0.1.0", "0.1.4", "0.2.0"]); - -        assert!(VersionReq::parse("> 0.1.0,").is_err()); -        assert!(VersionReq::parse("> 0.3.0, ,").is_err()); - -        let r = req(">=0.5.1-alpha3, <0.6"); -        assert_eq!(r.to_string(), ">= 0.5.1-alpha3, < 0.6".to_string()); -        assert_match(&r, -                     &["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"]); -        assert_not_match(&r, -                         &["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre"]); -        assert_not_match(&r, &["0.6.0", "0.6.0-pre"]); -    } - -    #[test] -    pub fn test_parsing_tilde() { -        let r = req("~1"); -        assert_match(&r, &["1.0.0", "1.0.1", "1.1.1"]); -        assert_not_match(&r, &["0.9.1", "2.9.0", "0.0.9"]); - -        let r = req("~1.2"); -        assert_match(&r, &["1.2.0", "1.2.1"]); -        assert_not_match(&r, &["1.1.1", "1.3.0", "0.0.9"]); - -        let r = req("~1.2.2"); -        assert_match(&r, &["1.2.2", "1.2.4"]); -        assert_not_match(&r, &["1.2.1", "1.9.0", "1.0.9", "2.0.1", "0.1.3"]); - -        let r = req("~1.2.3-beta.2"); -        assert_match(&r, &["1.2.3", "1.2.4", "1.2.3-beta.2", "1.2.3-beta.4"]); -        assert_not_match(&r, &["1.3.3", "1.1.4", "1.2.3-beta.1", "1.2.4-beta.2"]); -    } - -    #[test] -    pub fn test_parsing_compatible() { -        let r = req("^1"); -        assert_match(&r, &["1.1.2", "1.1.0", "1.2.1", "1.0.1"]); -        assert_not_match(&r, &["0.9.1", "2.9.0", "0.1.4"]); -        assert_not_match(&r, &["1.0.0-beta1", "0.1.0-alpha", "1.0.1-pre"]); - -        let r = req("^1.1"); -        assert_match(&r, &["1.1.2", "1.1.0", "1.2.1"]); -        assert_not_match(&r, &["0.9.1", "2.9.0", "1.0.1", "0.1.4"]); - -        let r = req("^1.1.2"); -        assert_match(&r, &["1.1.2", "1.1.4", "1.2.1"]); -        assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]); -        assert_not_match(&r, &["1.1.2-alpha1", "1.1.3-alpha1", "2.9.0-alpha1"]); - -        let r = req("^0.1.2"); -        assert_match(&r, &["0.1.2", "0.1.4"]); -        assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1"]); -        assert_not_match(&r, &["0.1.2-beta", "0.1.3-alpha", "0.2.0-pre"]); - -        let r = req("^0.5.1-alpha3"); -        assert_match(&r, -                     &["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"]); -        assert_not_match(&r, -                         &["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre", "0.6.0"]); - -        let r = req("^0.0.2"); -        assert_match(&r, &["0.0.2"]); -        assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.0.1", "0.1.4"]); - -        let r = req("^0.0"); -        assert_match(&r, &["0.0.2", "0.0.0"]); -        assert_not_match(&r, &["0.9.1", "2.9.0", "1.1.1", "0.1.4"]); - -        let r = req("^0"); -        assert_match(&r, &["0.9.1", "0.0.2", "0.0.0"]); -        assert_not_match(&r, &["2.9.0", "1.1.1"]); - -        let r = req("^1.4.2-beta.5"); -        assert_match(&r, -                     &["1.4.2", "1.4.3", "1.4.2-beta.5", "1.4.2-beta.6", "1.4.2-c"]); -        assert_not_match(&r, -                         &["0.9.9", "2.0.0", "1.4.2-alpha", "1.4.2-beta.4", "1.4.3-beta.5"]); -    } - -    #[test] -    pub fn test_parsing_wildcard() { -        let r = req(""); -        assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]); -        assert_not_match(&r, &[]); -        let r = req("*"); -        assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]); -        assert_not_match(&r, &[]); -        let r = req("x"); -        assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]); -        assert_not_match(&r, &[]); -        let r = req("X"); -        assert_match(&r, &["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"]); -        assert_not_match(&r, &[]); - -        let r = req("1.*"); -        assert_match(&r, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]); -        assert_not_match(&r, &["0.0.9"]); -        let r = req("1.x"); -        assert_match(&r, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]); -        assert_not_match(&r, &["0.0.9"]); -        let r = req("1.X"); -        assert_match(&r, &["1.2.0", "1.2.1", "1.1.1", "1.3.0"]); -        assert_not_match(&r, &["0.0.9"]); - -        let r = req("1.2.*"); -        assert_match(&r, &["1.2.0", "1.2.2", "1.2.4"]); -        assert_not_match(&r, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]); -        let r = req("1.2.x"); -        assert_match(&r, &["1.2.0", "1.2.2", "1.2.4"]); -        assert_not_match(&r, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]); -        let r = req("1.2.X"); -        assert_match(&r, &["1.2.0", "1.2.2", "1.2.4"]); -        assert_not_match(&r, &["1.9.0", "1.0.9", "2.0.1", "0.1.3"]); -    } - -    #[test] -    pub fn test_any() { -        let r = VersionReq::any(); -        assert_match(&r, &["0.0.1", "0.1.0", "1.0.0"]); -    } - -    #[test] -    pub fn test_pre() { -        let r = req("=2.1.1-really.0"); -        assert_match(&r, &["2.1.1-really.0"]); -    } - -    // #[test] -    // pub fn test_parse_errors() { -    //    assert_eq!(Err(InvalidVersionRequirement), VersionReq::parse("\0")); -    //    assert_eq!(Err(OpAlreadySet), VersionReq::parse(">= >= 0.0.2")); -    //    assert_eq!(Err(InvalidSigil), VersionReq::parse(">== 0.0.2")); -    //    assert_eq!(Err(VersionComponentsMustBeNumeric), -    //               VersionReq::parse("a.0.0")); -    //    assert_eq!(Err(InvalidIdentifier), VersionReq::parse("1.0.0-")); -    //    assert_eq!(Err(MajorVersionRequired), VersionReq::parse(">=")); -    // } - -    #[test] -    pub fn test_from_str() { -        assert_eq!("1.0.0".parse::<VersionReq>().unwrap().to_string(), -                   "^1.0.0".to_string()); -        assert_eq!("=1.0.0".parse::<VersionReq>().unwrap().to_string(), -                   "= 1.0.0".to_string()); -        assert_eq!("~1".parse::<VersionReq>().unwrap().to_string(), -                   "~1".to_string()); -        assert_eq!("~1.2".parse::<VersionReq>().unwrap().to_string(), -                   "~1.2".to_string()); -        assert_eq!("^1".parse::<VersionReq>().unwrap().to_string(), -                   "^1".to_string()); -        assert_eq!("^1.1".parse::<VersionReq>().unwrap().to_string(), -                   "^1.1".to_string()); -        assert_eq!("*".parse::<VersionReq>().unwrap().to_string(), -                   "*".to_string()); -        assert_eq!("1.*".parse::<VersionReq>().unwrap().to_string(), -                   "1.*".to_string()); -        assert_eq!("< 1.0.0".parse::<VersionReq>().unwrap().to_string(), -                   "< 1.0.0".to_string()); -    } - -    // #[test] -    // pub fn test_from_str_errors() { -    //    assert_eq!(Err(InvalidVersionRequirement), "\0".parse::<VersionReq>()); -    //    assert_eq!(Err(OpAlreadySet), ">= >= 0.0.2".parse::<VersionReq>()); -    //    assert_eq!(Err(InvalidSigil), ">== 0.0.2".parse::<VersionReq>()); -    //    assert_eq!(Err(VersionComponentsMustBeNumeric), -    //               "a.0.0".parse::<VersionReq>()); -    //    assert_eq!(Err(InvalidIdentifier), "1.0.0-".parse::<VersionReq>()); -    //    assert_eq!(Err(MajorVersionRequired), ">=".parse::<VersionReq>()); -    // } - -    #[test] -    fn test_cargo3202() { -        let v = "0.*.*".parse::<VersionReq>().unwrap(); -        assert_eq!("0.*.*", format!("{}", v.predicates[0])); - -        let v = "0.0.*".parse::<VersionReq>().unwrap(); -        assert_eq!("0.0.*", format!("{}", v.predicates[0])); - -        let r = req("0.*.*"); -        assert_match(&r, &["0.5.0"]); -    } - -    #[test] -    fn test_eq_hash() { -        assert!(req("^1") == req("^1")); -        assert!(calculate_hash(req("^1")) == calculate_hash(req("^1"))); -        assert!(req("^1") != req("^2")); -    } - -    #[test] -    fn test_ordering() { -        assert!(req("=1") < req("*")); -        assert!(req(">1") < req("*")); -        assert!(req(">=1") < req("*")); -        assert!(req("<1") < req("*")); -        assert!(req("<=1") < req("*")); -        assert!(req("~1") < req("*")); -        assert!(req("^1") < req("*")); -        assert!(req("*") == req("*")); -    } -} | 
