]> git.proxmox.com Git - rustc.git/blob - vendor/semver-0.9.0/src/version.rs
New upstream version 1.45.0+dfsg1
[rustc.git] / vendor / semver-0.9.0 / src / version.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! The `version` module gives you tools to create and compare SemVer-compliant
12 //! versions.
13
14 use std::cmp::{self, Ordering};
15 use std::fmt;
16 use std::hash;
17 use std::error::Error;
18
19 use std::result;
20 use std::str;
21
22 use semver_parser;
23
24 #[cfg(feature = "serde")]
25 use serde::ser::{Serialize, Serializer};
26 #[cfg(feature = "serde")]
27 use serde::de::{self, Deserialize, Deserializer, Visitor};
28
29 /// An identifier in the pre-release or build metadata.
30 ///
31 /// See sections 9 and 10 of the spec for more about pre-release identifers and
32 /// build metadata.
33 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
34 pub enum Identifier {
35 /// An identifier that's solely numbers.
36 Numeric(u64),
37 /// An identifier with letters and numbers.
38 AlphaNumeric(String),
39 }
40
41 impl From<semver_parser::version::Identifier> for Identifier {
42 fn from(other: semver_parser::version::Identifier) -> Identifier {
43 match other {
44 semver_parser::version::Identifier::Numeric(n) => Identifier::Numeric(n),
45 semver_parser::version::Identifier::AlphaNumeric(s) => Identifier::AlphaNumeric(s),
46 }
47 }
48 }
49
50 impl fmt::Display for Identifier {
51 #[inline]
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 match *self {
54 Identifier::Numeric(ref n) => fmt::Display::fmt(n, f),
55 Identifier::AlphaNumeric(ref s) => fmt::Display::fmt(s, f),
56 }
57 }
58 }
59
60 #[cfg(feature = "serde")]
61 impl Serialize for Identifier {
62 fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
63 where S: Serializer
64 {
65 // Serialize Identifier as a number or string.
66 match *self {
67 Identifier::Numeric(n) => serializer.serialize_u64(n),
68 Identifier::AlphaNumeric(ref s) => serializer.serialize_str(s),
69 }
70 }
71 }
72
73 #[cfg(feature = "serde")]
74 impl<'de> Deserialize<'de> for Identifier {
75 fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
76 where D: Deserializer<'de>
77 {
78 struct IdentifierVisitor;
79
80 // Deserialize Identifier from a number or string.
81 impl<'de> Visitor<'de> for IdentifierVisitor {
82 type Value = Identifier;
83
84 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
85 formatter.write_str("a SemVer pre-release or build identifier")
86 }
87
88 fn visit_u64<E>(self, numeric: u64) -> result::Result<Self::Value, E>
89 where E: de::Error
90 {
91 Ok(Identifier::Numeric(numeric))
92 }
93
94 fn visit_str<E>(self, alphanumeric: &str) -> result::Result<Self::Value, E>
95 where E: de::Error
96 {
97 Ok(Identifier::AlphaNumeric(alphanumeric.to_owned()))
98 }
99 }
100
101 deserializer.deserialize_any(IdentifierVisitor)
102 }
103 }
104
105 /// Represents a version number conforming to the semantic versioning scheme.
106 #[derive(Clone, Eq, Debug)]
107 pub struct Version {
108 /// The major version, to be incremented on incompatible changes.
109 pub major: u64,
110 /// The minor version, to be incremented when functionality is added in a
111 /// backwards-compatible manner.
112 pub minor: u64,
113 /// The patch version, to be incremented when backwards-compatible bug
114 /// fixes are made.
115 pub patch: u64,
116 /// The pre-release version identifier, if one exists.
117 pub pre: Vec<Identifier>,
118 /// The build metadata, ignored when determining version precedence.
119 pub build: Vec<Identifier>,
120 }
121
122 impl From<semver_parser::version::Version> for Version {
123 fn from(other: semver_parser::version::Version) -> Version {
124 Version {
125 major: other.major,
126 minor: other.minor,
127 patch: other.patch,
128 pre: other.pre.into_iter().map(From::from).collect(),
129 build: other.build.into_iter().map(From::from).collect(),
130 }
131 }
132 }
133
134 #[cfg(feature = "serde")]
135 impl Serialize for Version {
136 fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
137 where S: Serializer
138 {
139 // Serialize Version as a string.
140 serializer.collect_str(self)
141 }
142 }
143
144 #[cfg(feature = "serde")]
145 impl<'de> Deserialize<'de> for Version {
146 fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
147 where D: Deserializer<'de>
148 {
149 struct VersionVisitor;
150
151 // Deserialize Version from a string.
152 impl<'de> Visitor<'de> for VersionVisitor {
153 type Value = Version;
154
155 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
156 formatter.write_str("a SemVer version as a string")
157 }
158
159 fn visit_str<E>(self, v: &str) -> result::Result<Self::Value, E>
160 where E: de::Error
161 {
162 Version::parse(v).map_err(de::Error::custom)
163 }
164 }
165
166 deserializer.deserialize_str(VersionVisitor)
167 }
168 }
169
170 /// An error type for this crate
171 ///
172 /// Currently, just a generic error. Will make this nicer later.
173 #[derive(Clone,PartialEq,Debug,PartialOrd)]
174 pub enum SemVerError {
175 /// An error ocurred while parsing.
176 ParseError(String),
177 }
178
179 impl fmt::Display for SemVerError {
180 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
181 match self {
182 &SemVerError::ParseError(ref m) => write!(f, "{}", m),
183 }
184 }
185 }
186
187 impl Error for SemVerError {
188 fn description(&self) -> &str {
189 match self {
190 &SemVerError::ParseError(ref m) => m,
191 }
192 }
193 }
194
195 /// A Result type for errors
196 pub type Result<T> = result::Result<T, SemVerError>;
197
198 impl Version {
199
200 /// Contructs the simple case without pre or build.
201 pub fn new(major: u64, minor: u64, patch: u64) -> Version {
202 Version {
203 major: major,
204 minor: minor,
205 patch: patch,
206 pre: Vec::new(),
207 build: Vec::new()
208 }
209 }
210
211 /// Parse a string into a semver object.
212 pub fn parse(version: &str) -> Result<Version> {
213 let res = semver_parser::version::parse(version);
214
215 match res {
216 // Convert plain String error into proper ParseError
217 Err(e) => Err(SemVerError::ParseError(e)),
218 Ok(v) => Ok(From::from(v)),
219 }
220 }
221
222 /// Clears the build metadata
223 fn clear_metadata(&mut self) {
224 self.build = Vec::new();
225 self.pre = Vec::new();
226 }
227
228 /// Increments the patch number for this Version (Must be mutable)
229 pub fn increment_patch(&mut self) {
230 self.patch += 1;
231 self.clear_metadata();
232 }
233
234 /// Increments the minor version number for this Version (Must be mutable)
235 ///
236 /// As instructed by section 7 of the spec, the patch number is reset to 0.
237 pub fn increment_minor(&mut self) {
238 self.minor += 1;
239 self.patch = 0;
240 self.clear_metadata();
241 }
242
243 /// Increments the major version number for this Version (Must be mutable)
244 ///
245 /// As instructed by section 8 of the spec, the minor and patch numbers are
246 /// reset to 0
247 pub fn increment_major(&mut self) {
248 self.major += 1;
249 self.minor = 0;
250 self.patch = 0;
251 self.clear_metadata();
252 }
253
254 /// Checks to see if the current Version is in pre-release status
255 pub fn is_prerelease(&self) -> bool {
256 !self.pre.is_empty()
257 }
258 }
259
260 impl str::FromStr for Version {
261 type Err = SemVerError;
262
263 fn from_str(s: &str) -> Result<Version> {
264 Version::parse(s)
265 }
266 }
267
268 impl fmt::Display for Version {
269 #[inline]
270 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271 try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch));
272 if !self.pre.is_empty() {
273 try!(write!(f, "-"));
274 for (i, x) in self.pre.iter().enumerate() {
275 if i != 0 {
276 try!(write!(f, "."))
277 }
278 try!(write!(f, "{}", x));
279 }
280 }
281 if !self.build.is_empty() {
282 try!(write!(f, "+"));
283 for (i, x) in self.build.iter().enumerate() {
284 if i != 0 {
285 try!(write!(f, "."))
286 }
287 try!(write!(f, "{}", x));
288 }
289 }
290 Ok(())
291 }
292 }
293
294 impl cmp::PartialEq for Version {
295 #[inline]
296 fn eq(&self, other: &Version) -> bool {
297 // We should ignore build metadata here, otherwise versions v1 and v2
298 // can exist such that !(v1 < v2) && !(v1 > v2) && v1 != v2, which
299 // violate strict total ordering rules.
300 self.major == other.major && self.minor == other.minor && self.patch == other.patch &&
301 self.pre == other.pre
302 }
303 }
304
305 impl cmp::PartialOrd for Version {
306 fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
307 Some(self.cmp(other))
308 }
309 }
310
311 impl cmp::Ord for Version {
312 fn cmp(&self, other: &Version) -> Ordering {
313 match self.major.cmp(&other.major) {
314 Ordering::Equal => {}
315 r => return r,
316 }
317
318 match self.minor.cmp(&other.minor) {
319 Ordering::Equal => {}
320 r => return r,
321 }
322
323 match self.patch.cmp(&other.patch) {
324 Ordering::Equal => {}
325 r => return r,
326 }
327
328 // NB: semver spec says 0.0.0-pre < 0.0.0
329 // but the version of ord defined for vec
330 // says that [] < [pre] so we alter it here
331 match (self.pre.len(), other.pre.len()) {
332 (0, 0) => Ordering::Equal,
333 (0, _) => Ordering::Greater,
334 (_, 0) => Ordering::Less,
335 (_, _) => self.pre.cmp(&other.pre),
336 }
337 }
338 }
339
340 impl hash::Hash for Version {
341 fn hash<H: hash::Hasher>(&self, into: &mut H) {
342 self.major.hash(into);
343 self.minor.hash(into);
344 self.patch.hash(into);
345 self.pre.hash(into);
346 }
347 }
348
349 impl From<(u64,u64,u64)> for Version {
350 fn from(tuple: (u64,u64,u64)) -> Version {
351 let (major, minor, patch) = tuple;
352 Version::new(major, minor, patch)
353 }
354 }
355
356 #[cfg(test)]
357 mod tests {
358 use std::result;
359 use super::Version;
360 use super::Identifier;
361 use super::SemVerError;
362
363 #[test]
364 fn test_parse() {
365 fn parse_error(e: &str) -> result::Result<Version, SemVerError> {
366 return Err(SemVerError::ParseError(e.to_string()));
367 }
368
369 assert_eq!(Version::parse(""),
370 parse_error("Error parsing major identifier"));
371 assert_eq!(Version::parse(" "),
372 parse_error("Error parsing major identifier"));
373 assert_eq!(Version::parse("1"),
374 parse_error("Expected dot"));
375 assert_eq!(Version::parse("1.2"),
376 parse_error("Expected dot"));
377 assert_eq!(Version::parse("1.2.3-"),
378 parse_error("Error parsing prerelease"));
379 assert_eq!(Version::parse("a.b.c"),
380 parse_error("Error parsing major identifier"));
381 assert_eq!(Version::parse("1.2.3 abc"),
382 parse_error("Extra junk after valid version: abc"));
383
384 assert_eq!(Version::parse("1.2.3"),
385 Ok(Version {
386 major: 1,
387 minor: 2,
388 patch: 3,
389 pre: Vec::new(),
390 build: Vec::new(),
391 }));
392
393 assert_eq!(Version::parse("1.2.3"),
394 Ok(Version::new(1,2,3)));
395
396 assert_eq!(Version::parse(" 1.2.3 "),
397 Ok(Version {
398 major: 1,
399 minor: 2,
400 patch: 3,
401 pre: Vec::new(),
402 build: Vec::new(),
403 }));
404 assert_eq!(Version::parse("1.2.3-alpha1"),
405 Ok(Version {
406 major: 1,
407 minor: 2,
408 patch: 3,
409 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
410 build: Vec::new(),
411 }));
412 assert_eq!(Version::parse(" 1.2.3-alpha1 "),
413 Ok(Version {
414 major: 1,
415 minor: 2,
416 patch: 3,
417 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
418 build: Vec::new(),
419 }));
420 assert_eq!(Version::parse("1.2.3+build5"),
421 Ok(Version {
422 major: 1,
423 minor: 2,
424 patch: 3,
425 pre: Vec::new(),
426 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
427 }));
428 assert_eq!(Version::parse(" 1.2.3+build5 "),
429 Ok(Version {
430 major: 1,
431 minor: 2,
432 patch: 3,
433 pre: Vec::new(),
434 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
435 }));
436 assert_eq!(Version::parse("1.2.3-alpha1+build5"),
437 Ok(Version {
438 major: 1,
439 minor: 2,
440 patch: 3,
441 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
442 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
443 }));
444 assert_eq!(Version::parse(" 1.2.3-alpha1+build5 "),
445 Ok(Version {
446 major: 1,
447 minor: 2,
448 patch: 3,
449 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
450 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
451 }));
452 assert_eq!(Version::parse("1.2.3-1.alpha1.9+build5.7.3aedf "),
453 Ok(Version {
454 major: 1,
455 minor: 2,
456 patch: 3,
457 pre: vec![Identifier::Numeric(1),
458 Identifier::AlphaNumeric(String::from("alpha1")),
459 Identifier::Numeric(9),
460 ],
461 build: vec![Identifier::AlphaNumeric(String::from("build5")),
462 Identifier::Numeric(7),
463 Identifier::AlphaNumeric(String::from("3aedf")),
464 ],
465 }));
466 assert_eq!(Version::parse("0.4.0-beta.1+0851523"),
467 Ok(Version {
468 major: 0,
469 minor: 4,
470 patch: 0,
471 pre: vec![Identifier::AlphaNumeric(String::from("beta")),
472 Identifier::Numeric(1),
473 ],
474 build: vec![Identifier::AlphaNumeric(String::from("0851523"))],
475 }));
476
477 }
478
479 #[test]
480 fn test_increment_patch() {
481 let mut buggy_release = Version::parse("0.1.0").unwrap();
482 buggy_release.increment_patch();
483 assert_eq!(buggy_release, Version::parse("0.1.1").unwrap());
484 }
485
486 #[test]
487 fn test_increment_minor() {
488 let mut feature_release = Version::parse("1.4.6").unwrap();
489 feature_release.increment_minor();
490 assert_eq!(feature_release, Version::parse("1.5.0").unwrap());
491 }
492
493 #[test]
494 fn test_increment_major() {
495 let mut chrome_release = Version::parse("46.1.246773").unwrap();
496 chrome_release.increment_major();
497 assert_eq!(chrome_release, Version::parse("47.0.0").unwrap());
498 }
499
500 #[test]
501 fn test_increment_keep_prerelease() {
502 let mut release = Version::parse("1.0.0-alpha").unwrap();
503 release.increment_patch();
504
505 assert_eq!(release, Version::parse("1.0.1").unwrap());
506
507 release.increment_minor();
508
509 assert_eq!(release, Version::parse("1.1.0").unwrap());
510
511 release.increment_major();
512
513 assert_eq!(release, Version::parse("2.0.0").unwrap());
514 }
515
516
517 #[test]
518 fn test_increment_clear_metadata() {
519 let mut release = Version::parse("1.0.0+4442").unwrap();
520 release.increment_patch();
521
522 assert_eq!(release, Version::parse("1.0.1").unwrap());
523 release = Version::parse("1.0.1+hello").unwrap();
524
525 release.increment_minor();
526
527 assert_eq!(release, Version::parse("1.1.0").unwrap());
528 release = Version::parse("1.1.3747+hello").unwrap();
529
530 release.increment_major();
531
532 assert_eq!(release, Version::parse("2.0.0").unwrap());
533 }
534
535 #[test]
536 fn test_eq() {
537 assert_eq!(Version::parse("1.2.3"), Version::parse("1.2.3"));
538 assert_eq!(Version::parse("1.2.3-alpha1"),
539 Version::parse("1.2.3-alpha1"));
540 assert_eq!(Version::parse("1.2.3+build.42"),
541 Version::parse("1.2.3+build.42"));
542 assert_eq!(Version::parse("1.2.3-alpha1+42"),
543 Version::parse("1.2.3-alpha1+42"));
544 assert_eq!(Version::parse("1.2.3+23"), Version::parse("1.2.3+42"));
545 }
546
547 #[test]
548 fn test_ne() {
549 assert!(Version::parse("0.0.0") != Version::parse("0.0.1"));
550 assert!(Version::parse("0.0.0") != Version::parse("0.1.0"));
551 assert!(Version::parse("0.0.0") != Version::parse("1.0.0"));
552 assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta"));
553 }
554
555 #[test]
556 fn test_show() {
557 assert_eq!(format!("{}", Version::parse("1.2.3").unwrap()),
558 "1.2.3".to_string());
559 assert_eq!(format!("{}", Version::parse("1.2.3-alpha1").unwrap()),
560 "1.2.3-alpha1".to_string());
561 assert_eq!(format!("{}", Version::parse("1.2.3+build.42").unwrap()),
562 "1.2.3+build.42".to_string());
563 assert_eq!(format!("{}", Version::parse("1.2.3-alpha1+42").unwrap()),
564 "1.2.3-alpha1+42".to_string());
565 }
566
567 #[test]
568 fn test_to_string() {
569 assert_eq!(Version::parse("1.2.3").unwrap().to_string(),
570 "1.2.3".to_string());
571 assert_eq!(Version::parse("1.2.3-alpha1").unwrap().to_string(),
572 "1.2.3-alpha1".to_string());
573 assert_eq!(Version::parse("1.2.3+build.42").unwrap().to_string(),
574 "1.2.3+build.42".to_string());
575 assert_eq!(Version::parse("1.2.3-alpha1+42").unwrap().to_string(),
576 "1.2.3-alpha1+42".to_string());
577 }
578
579 #[test]
580 fn test_lt() {
581 assert!(Version::parse("0.0.0") < Version::parse("1.2.3-alpha2"));
582 assert!(Version::parse("1.0.0") < Version::parse("1.2.3-alpha2"));
583 assert!(Version::parse("1.2.0") < Version::parse("1.2.3-alpha2"));
584 assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3"));
585 assert!(Version::parse("1.2.3-alpha1") < Version::parse("1.2.3-alpha2"));
586 assert!(!(Version::parse("1.2.3-alpha2") < Version::parse("1.2.3-alpha2")));
587 assert!(!(Version::parse("1.2.3+23") < Version::parse("1.2.3+42")));
588 }
589
590 #[test]
591 fn test_le() {
592 assert!(Version::parse("0.0.0") <= Version::parse("1.2.3-alpha2"));
593 assert!(Version::parse("1.0.0") <= Version::parse("1.2.3-alpha2"));
594 assert!(Version::parse("1.2.0") <= Version::parse("1.2.3-alpha2"));
595 assert!(Version::parse("1.2.3-alpha1") <= Version::parse("1.2.3-alpha2"));
596 assert!(Version::parse("1.2.3-alpha2") <= Version::parse("1.2.3-alpha2"));
597 assert!(Version::parse("1.2.3+23") <= Version::parse("1.2.3+42"));
598 }
599
600 #[test]
601 fn test_gt() {
602 assert!(Version::parse("1.2.3-alpha2") > Version::parse("0.0.0"));
603 assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.0.0"));
604 assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.0"));
605 assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha1"));
606 assert!(Version::parse("1.2.3") > Version::parse("1.2.3-alpha2"));
607 assert!(!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.3-alpha2")));
608 assert!(!(Version::parse("1.2.3+23") > Version::parse("1.2.3+42")));
609 }
610
611 #[test]
612 fn test_ge() {
613 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("0.0.0"));
614 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.0.0"));
615 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.0"));
616 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha1"));
617 assert!(Version::parse("1.2.3-alpha2") >= Version::parse("1.2.3-alpha2"));
618 assert!(Version::parse("1.2.3+23") >= Version::parse("1.2.3+42"));
619 }
620
621 #[test]
622 fn test_prerelease_check() {
623 assert!(Version::parse("1.0.0").unwrap().is_prerelease() == false);
624 assert!(Version::parse("0.0.1").unwrap().is_prerelease() == false);
625 assert!(Version::parse("4.1.4-alpha").unwrap().is_prerelease());
626 assert!(Version::parse("1.0.0-beta294296").unwrap().is_prerelease());
627 }
628
629 #[test]
630 fn test_spec_order() {
631 let vs = ["1.0.0-alpha",
632 "1.0.0-alpha.1",
633 "1.0.0-alpha.beta",
634 "1.0.0-beta",
635 "1.0.0-beta.2",
636 "1.0.0-beta.11",
637 "1.0.0-rc.1",
638 "1.0.0"];
639 let mut i = 1;
640 while i < vs.len() {
641 let a = Version::parse(vs[i - 1]);
642 let b = Version::parse(vs[i]);
643 assert!(a < b, "nope {:?} < {:?}", a, b);
644 i += 1;
645 }
646 }
647
648 #[test]
649 fn test_from_str() {
650 assert_eq!("1.2.3".parse(),
651 Ok(Version {
652 major: 1,
653 minor: 2,
654 patch: 3,
655 pre: Vec::new(),
656 build: Vec::new(),
657 }));
658 assert_eq!(" 1.2.3 ".parse(),
659 Ok(Version {
660 major: 1,
661 minor: 2,
662 patch: 3,
663 pre: Vec::new(),
664 build: Vec::new(),
665 }));
666 assert_eq!("1.2.3-alpha1".parse(),
667 Ok(Version {
668 major: 1,
669 minor: 2,
670 patch: 3,
671 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
672 build: Vec::new(),
673 }));
674 assert_eq!(" 1.2.3-alpha1 ".parse(),
675 Ok(Version {
676 major: 1,
677 minor: 2,
678 patch: 3,
679 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
680 build: Vec::new(),
681 }));
682 assert_eq!("1.2.3+build5".parse(),
683 Ok(Version {
684 major: 1,
685 minor: 2,
686 patch: 3,
687 pre: Vec::new(),
688 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
689 }));
690 assert_eq!(" 1.2.3+build5 ".parse(),
691 Ok(Version {
692 major: 1,
693 minor: 2,
694 patch: 3,
695 pre: Vec::new(),
696 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
697 }));
698 assert_eq!("1.2.3-alpha1+build5".parse(),
699 Ok(Version {
700 major: 1,
701 minor: 2,
702 patch: 3,
703 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
704 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
705 }));
706 assert_eq!(" 1.2.3-alpha1+build5 ".parse(),
707 Ok(Version {
708 major: 1,
709 minor: 2,
710 patch: 3,
711 pre: vec![Identifier::AlphaNumeric(String::from("alpha1"))],
712 build: vec![Identifier::AlphaNumeric(String::from("build5"))],
713 }));
714 assert_eq!("1.2.3-1.alpha1.9+build5.7.3aedf ".parse(),
715 Ok(Version {
716 major: 1,
717 minor: 2,
718 patch: 3,
719 pre: vec![Identifier::Numeric(1),
720 Identifier::AlphaNumeric(String::from("alpha1")),
721 Identifier::Numeric(9),
722 ],
723 build: vec![Identifier::AlphaNumeric(String::from("build5")),
724 Identifier::Numeric(7),
725 Identifier::AlphaNumeric(String::from("3aedf")),
726 ],
727 }));
728 assert_eq!("0.4.0-beta.1+0851523".parse(),
729 Ok(Version {
730 major: 0,
731 minor: 4,
732 patch: 0,
733 pre: vec![Identifier::AlphaNumeric(String::from("beta")),
734 Identifier::Numeric(1),
735 ],
736 build: vec![Identifier::AlphaNumeric(String::from("0851523"))],
737 }));
738
739 }
740
741 #[test]
742 fn test_from_str_errors() {
743 fn parse_error(e: &str) -> result::Result<Version, SemVerError> {
744 return Err(SemVerError::ParseError(e.to_string()));
745 }
746
747 assert_eq!("".parse(), parse_error("Error parsing major identifier"));
748 assert_eq!(" ".parse(), parse_error("Error parsing major identifier"));
749 assert_eq!("1".parse(), parse_error("Expected dot"));
750 assert_eq!("1.2".parse(),
751 parse_error("Expected dot"));
752 assert_eq!("1.2.3-".parse(),
753 parse_error("Error parsing prerelease"));
754 assert_eq!("a.b.c".parse(),
755 parse_error("Error parsing major identifier"));
756 assert_eq!("1.2.3 abc".parse(),
757 parse_error("Extra junk after valid version: abc"));
758 }
759 }