diff options
Diffstat (limited to 'semver-parser/src/version.rs')
-rw-r--r-- | semver-parser/src/version.rs | 365 |
1 files changed, 0 insertions, 365 deletions
diff --git a/semver-parser/src/version.rs b/semver-parser/src/version.rs deleted file mode 100644 index 570f947..0000000 --- a/semver-parser/src/version.rs +++ /dev/null @@ -1,365 +0,0 @@ -use std::fmt; -use std::str::from_utf8; - -use recognize::*; - -use common::{self, numeric_identifier}; - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Version { - pub major: u64, - pub minor: u64, - pub patch: u64, - pub pre: Vec<Identifier>, - pub build: Vec<Identifier>, -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum Identifier { - /// An identifier that's solely numbers. - Numeric(u64), - /// An identifier with letters and numbers. - AlphaNumeric(String), -} - -pub fn parse(version: &str) -> Result<Version, String> { - let s = version.trim().as_bytes(); - let mut i = 0; - let major = if let Some((major, len)) = numeric_identifier(&s[i..]) { - i += len; - major - } else { - return Err("Error parsing major identifier".to_string()); - }; - if let Some(len) = b'.'.p(&s[i..]) { - i += len; - } else { - return Err("Expected dot".to_string()); - } - let minor = if let Some((minor, len)) = numeric_identifier(&s[i..]) { - i += len; - minor - } else { - return Err("Error parsing minor identifier".to_string()); - }; - if let Some(len) = b'.'.p(&s[i..]) { - i += len; - } else { - return Err("Expected dot".to_string()); - } - let patch = if let Some((patch, len)) = numeric_identifier(&s[i..]) { - i += len; - patch - } else { - return Err("Error parsing patch identifier".to_string()); - }; - let (pre, pre_len) = common::parse_optional_meta(&s[i..], b'-')?; - i += pre_len; - let (build, build_len) = common::parse_optional_meta(&s[i..], b'+')?; - i += build_len; - if i != s.len() { - return Err("Extra junk after valid version: ".to_string() + - from_utf8(&s[i..]).unwrap()); - } - Ok(Version { - major: major, - minor: minor, - patch: patch, - pre: pre, - build: build, - }) -} - -impl fmt::Display for Version { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch)); - if !self.pre.is_empty() { - let strs: Vec<_> = - self.pre.iter().map(ToString::to_string).collect(); - try!(write!(f, "-{}", strs.join("."))); - } - if !self.build.is_empty() { - let strs: Vec<_> = - self.build.iter().map(ToString::to_string).collect(); - try!(write!(f, "+{}", strs.join("."))); - } - Ok(()) - } -} - -impl fmt::Display for Identifier { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Identifier::Numeric(ref id) => id.fmt(f), - Identifier::AlphaNumeric(ref id) => id.fmt(f), - } - } -} - -#[cfg(test)] -mod tests { - use version; - use super::*; - - #[test] - fn parse_empty() { - let version = ""; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "empty string incorrectly considered a valid parse"); - } - - #[test] - fn parse_blank() { - let version = " "; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "blank string incorrectly considered a valid parse"); - } - - #[test] - fn parse_no_minor_patch() { - let version = "1"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version)); - } - - #[test] - fn parse_no_patch() { - let version = "1.2"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version)); - } - - #[test] - fn parse_empty_pre() { - let version = "1.2.3-"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version)); - } - - #[test] - fn parse_letters() { - let version = "a.b.c"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version)); - } - - #[test] - fn parse_with_letters() { - let version = "1.2.3 a.b.c"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), format!("'{}' incorrectly considered a valid parse", version)); - } - - #[test] - fn parse_basic_version() { - let version = "1.2.3"; - - let parsed = version::parse(version).unwrap(); - - assert_eq!(1, parsed.major); - assert_eq!(2, parsed.minor); - assert_eq!(3, parsed.patch); - } - - #[test] - fn parse_trims_input() { - let version = " 1.2.3 "; - - let parsed = version::parse(version).unwrap(); - - assert_eq!(1, parsed.major); - assert_eq!(2, parsed.minor); - assert_eq!(3, parsed.patch); - } - - #[test] - fn parse_no_major_leading_zeroes() { - let version = "01.0.0"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "01 incorrectly considered a valid major version"); - } - - #[test] - fn parse_no_minor_leading_zeroes() { - let version = "0.01.0"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "01 incorrectly considered a valid minor version"); - } - - #[test] - fn parse_no_patch_leading_zeroes() { - let version = "0.0.01"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "01 incorrectly considered a valid patch version"); - } - - #[test] - fn parse_no_major_overflow() { - let version = "98765432109876543210.0.0"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "98765432109876543210 incorrectly considered a valid major version"); - } - - #[test] - fn parse_no_minor_overflow() { - let version = "0.98765432109876543210.0"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "98765432109876543210 incorrectly considered a valid minor version"); - } - - #[test] - fn parse_no_patch_overflow() { - let version = "0.0.98765432109876543210"; - - let parsed = version::parse(version); - - assert!(parsed.is_err(), "98765432109876543210 incorrectly considered a valid patch version"); - } - - #[test] - fn parse_basic_prerelease() { - let version = "1.2.3-pre"; - - let parsed = version::parse(version).unwrap(); - - let expected_pre = vec![Identifier::AlphaNumeric(String::from("pre"))]; - assert_eq!(expected_pre, parsed.pre); - } - - #[test] - fn parse_prerelease_alphanumeric() { - let version = "1.2.3-alpha1"; - - let parsed = version::parse(version).unwrap(); - - let expected_pre = vec![Identifier::AlphaNumeric(String::from("alpha1"))]; - assert_eq!(expected_pre, parsed.pre); - } - - #[test] - fn parse_prerelease_zero() { - let version = "1.2.3-pre.0"; - - let parsed = version::parse(version).unwrap(); - - let expected_pre = vec![Identifier::AlphaNumeric(String::from("pre")), - Identifier::Numeric(0)]; - assert_eq!(expected_pre, parsed.pre); - } - - #[test] - fn parse_basic_build() { - let version = "1.2.3+build"; - - let parsed = version::parse(version).unwrap(); - - let expected_build = vec![Identifier::AlphaNumeric(String::from("build"))]; - assert_eq!(expected_build, parsed.build); - } - - #[test] - fn parse_build_alphanumeric() { - let version = "1.2.3+build5"; - - let parsed = version::parse(version).unwrap(); - - let expected_build = vec![Identifier::AlphaNumeric(String::from("build5"))]; - assert_eq!(expected_build, parsed.build); - } - - #[test] - fn parse_pre_and_build() { - let version = "1.2.3-alpha1+build5"; - - let parsed = version::parse(version).unwrap(); - - let expected_pre = vec![Identifier::AlphaNumeric(String::from("alpha1"))]; - assert_eq!(expected_pre, parsed.pre); - - let expected_build = vec![Identifier::AlphaNumeric(String::from("build5"))]; - assert_eq!(expected_build, parsed.build); - } - - #[test] - fn parse_complex_metadata_01() { - let version = "1.2.3-1.alpha1.9+build5.7.3aedf "; - - let parsed = version::parse(version).unwrap(); - - let expected_pre = vec![Identifier::Numeric(1), - Identifier::AlphaNumeric(String::from("alpha1")), - Identifier::Numeric(9)]; - assert_eq!(expected_pre, parsed.pre); - - let expected_build = vec![Identifier::AlphaNumeric(String::from("build5")), - Identifier::Numeric(7), - Identifier::AlphaNumeric(String::from("3aedf"))]; - assert_eq!(expected_build, parsed.build); - } - - #[test] - fn parse_complex_metadata_02() { - let version = "0.4.0-beta.1+0851523"; - - let parsed = version::parse(version).unwrap(); - - let expected_pre = vec![Identifier::AlphaNumeric(String::from("beta")), - Identifier::Numeric(1)]; - assert_eq!(expected_pre, parsed.pre); - - let expected_build = vec![Identifier::AlphaNumeric(String::from("0851523"))]; - assert_eq!(expected_build, parsed.build); - } - - #[test] - fn parse_metadata_overflow() { - let version = "0.4.0-beta.1+98765432109876543210"; - - let parsed = version::parse(version).unwrap(); - - let expected_pre = vec![Identifier::AlphaNumeric(String::from("beta")), - Identifier::Numeric(1)]; - assert_eq!(expected_pre, parsed.pre); - - let expected_build = vec![Identifier::AlphaNumeric(String::from("98765432109876543210"))]; - assert_eq!(expected_build, parsed.build); - } - - #[test] - fn parse_regression_01() { - let version = "0.0.0-WIP"; - - let parsed = version::parse(version).unwrap(); - - assert_eq!(0, parsed.major); - assert_eq!(0, parsed.minor); - assert_eq!(0, parsed.patch); - - let expected_pre = vec![Identifier::AlphaNumeric(String::from("WIP"))]; - assert_eq!(expected_pre, parsed.pre); - } -} |