1 //! [![github]](https://github.com/dtolnay/semver) [![crates-io]](https://crates.io/crates/semver) [![docs-rs]](https://docs.rs/semver)
2 //!
3 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6 //!
7 //! <br>
8 //!
9 //! A parser and evaluator for Cargo's flavor of Semantic Versioning.
10 //!
11 //! Semantic Versioning (see <https://semver.org>) is a guideline for how
12 //! version numbers are assigned and incremented. It is widely followed within
13 //! the Cargo/crates.io ecosystem for Rust.
14 //!
15 //! <br>
16 //!
17 //! # Example
18 //!
19 //! ```
20 //! use semver::{BuildMetadata, Prerelease, Version, VersionReq};
21 //!
22 //! fn main() {
23 //!     let req = VersionReq::parse(">=1.2.3, <1.8.0").unwrap();
24 //!
25 //!     // Check whether this requirement matches version 1.2.3-alpha.1 (no)
26 //!     let version = Version {
27 //!         major: 1,
28 //!         minor: 2,
29 //!         patch: 3,
30 //!         pre: Prerelease::new("alpha.1").unwrap(),
31 //!         build: BuildMetadata::EMPTY,
32 //!     };
33 //!     assert!(!req.matches(&version));
34 //!
35 //!     // Check whether it matches 1.3.0 (yes it does)
36 //!     let version = Version::parse("1.3.0").unwrap();
37 //!     assert!(req.matches(&version));
38 //! }
39 //! ```
40 //!
41 //! <br><br>
42 //!
43 //! # Scope of this crate
44 //!
45 //! Besides Cargo, several other package ecosystems and package managers for
46 //! other languages also use SemVer:&ensp;RubyGems/Bundler for Ruby, npm for
47 //! JavaScript, Composer for PHP, CocoaPods for Objective-C...
48 //!
49 //! The `semver` crate is specifically intended to implement Cargo's
50 //! interpretation of Semantic Versioning.
51 //!
52 //! Where the various tools differ in their interpretation or implementation of
53 //! the spec, this crate follows the implementation choices made by Cargo. If
54 //! you are operating on version numbers from some other package ecosystem, you
55 //! will want to use a different semver library which is appropriate to that
56 //! ecosystem.
57 //!
58 //! The extent of Cargo's SemVer support is documented in the *[Specifying
59 //! Dependencies]* chapter of the Cargo reference.
60 //!
61 //! [Specifying Dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
62 
63 #![doc(html_root_url = "https://docs.rs/semver/1.0.23")]
64 #![cfg_attr(doc_cfg, feature(doc_cfg))]
65 #![cfg_attr(all(not(feature = "std"), not(no_alloc_crate)), no_std)]
66 #![cfg_attr(not(no_unsafe_op_in_unsafe_fn_lint), deny(unsafe_op_in_unsafe_fn))]
67 #![cfg_attr(no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))]
68 #![cfg_attr(no_str_strip_prefix, allow(unstable_name_collisions))]
69 #![allow(
70     clippy::cast_lossless,
71     clippy::cast_possible_truncation,
72     clippy::doc_markdown,
73     clippy::incompatible_msrv,
74     clippy::items_after_statements,
75     clippy::manual_map,
76     clippy::match_bool,
77     clippy::missing_errors_doc,
78     clippy::must_use_candidate,
79     clippy::needless_doctest_main,
80     clippy::ptr_as_ptr,
81     clippy::redundant_else,
82     clippy::semicolon_if_nothing_returned, // https://github.com/rust-lang/rust-clippy/issues/7324
83     clippy::similar_names,
84     clippy::unnested_or_patterns,
85     clippy::unseparated_literal_suffix,
86     clippy::wildcard_imports
87 )]
88 
89 #[cfg(not(no_alloc_crate))]
90 extern crate alloc;
91 
92 mod backport;
93 mod display;
94 mod error;
95 mod eval;
96 mod identifier;
97 mod impls;
98 mod parse;
99 
100 #[cfg(feature = "serde")]
101 mod serde;
102 
103 use crate::identifier::Identifier;
104 use core::cmp::Ordering;
105 use core::str::FromStr;
106 
107 #[allow(unused_imports)]
108 use crate::backport::*;
109 
110 pub use crate::parse::Error;
111 
112 /// **SemVer version** as defined by <https://semver.org>.
113 ///
114 /// # Syntax
115 ///
116 /// - The major, minor, and patch numbers may be any integer 0 through u64::MAX.
117 ///   When representing a SemVer version as a string, each number is written as
118 ///   a base 10 integer. For example, `1.0.119`.
119 ///
120 /// - Leading zeros are forbidden in those positions. For example `1.01.00` is
121 ///   invalid as a SemVer version.
122 ///
123 /// - The pre-release identifier, if present, must conform to the syntax
124 ///   documented for [`Prerelease`].
125 ///
126 /// - The build metadata, if present, must conform to the syntax documented for
127 ///   [`BuildMetadata`].
128 ///
129 /// - Whitespace is not allowed anywhere in the version.
130 ///
131 /// # Total ordering
132 ///
133 /// Given any two SemVer versions, one is less than, greater than, or equal to
134 /// the other. Versions may be compared against one another using Rust's usual
135 /// comparison operators.
136 ///
137 /// - The major, minor, and patch number are compared numerically from left to
138 /// right, lexicographically ordered as a 3-tuple of integers. So for example
139 /// version `1.5.0` is less than version `1.19.0`, despite the fact that
140 /// "1.19.0" &lt; "1.5.0" as ASCIIbetically compared strings and 1.19 &lt; 1.5
141 /// as real numbers.
142 ///
143 /// - When major, minor, and patch are equal, a pre-release version is
144 ///   considered less than the ordinary release:&ensp;version `1.0.0-alpha.1` is
145 ///   less than version `1.0.0`.
146 ///
147 /// - Two pre-releases of the same major, minor, patch are compared by
148 ///   lexicographic ordering of dot-separated components of the pre-release
149 ///   string.
150 ///
151 ///   - Identifiers consisting of only digits are compared
152 ///     numerically:&ensp;`1.0.0-pre.8` is less than `1.0.0-pre.12`.
153 ///
154 ///   - Identifiers that contain a letter or hyphen are compared in ASCII sort
155 ///     order:&ensp;`1.0.0-pre12` is less than `1.0.0-pre8`.
156 ///
157 ///   - Any numeric identifier is always less than any non-numeric
158 ///     identifier:&ensp;`1.0.0-pre.1` is less than `1.0.0-pre.x`.
159 ///
160 /// Example:&ensp;`1.0.0-alpha`&ensp;&lt;&ensp;`1.0.0-alpha.1`&ensp;&lt;&ensp;`1.0.0-alpha.beta`&ensp;&lt;&ensp;`1.0.0-beta`&ensp;&lt;&ensp;`1.0.0-beta.2`&ensp;&lt;&ensp;`1.0.0-beta.11`&ensp;&lt;&ensp;`1.0.0-rc.1`&ensp;&lt;&ensp;`1.0.0`
161 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
162 pub struct Version {
163     pub major: u64,
164     pub minor: u64,
165     pub patch: u64,
166     pub pre: Prerelease,
167     pub build: BuildMetadata,
168 }
169 
170 /// **SemVer version requirement** describing the intersection of some version
171 /// comparators, such as `>=1.2.3, <1.8`.
172 ///
173 /// # Syntax
174 ///
175 /// - Either `*` (meaning "any"), or one or more comma-separated comparators.
176 ///
177 /// - A [`Comparator`] is an operator ([`Op`]) and a partial version, separated
178 ///   by optional whitespace. For example `>=1.0.0` or `>=1.0`.
179 ///
180 /// - Build metadata is syntactically permitted on the partial versions, but is
181 ///   completely ignored, as it's never relevant to whether any comparator
182 ///   matches a particular version.
183 ///
184 /// - Whitespace is permitted around commas and around operators. Whitespace is
185 ///   not permitted within a partial version, i.e. anywhere between the major
186 ///   version number and its minor, patch, pre-release, or build metadata.
187 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
188 #[cfg_attr(no_const_vec_new, derive(Default))]
189 pub struct VersionReq {
190     pub comparators: Vec<Comparator>,
191 }
192 
193 /// A pair of comparison operator and partial version, such as `>=1.2`. Forms
194 /// one piece of a VersionReq.
195 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
196 pub struct Comparator {
197     pub op: Op,
198     pub major: u64,
199     pub minor: Option<u64>,
200     /// Patch is only allowed if minor is Some.
201     pub patch: Option<u64>,
202     /// Non-empty pre-release is only allowed if patch is Some.
203     pub pre: Prerelease,
204 }
205 
206 /// SemVer comparison operator: `=`, `>`, `>=`, `<`, `<=`, `~`, `^`, `*`.
207 ///
208 /// # Op::Exact
209 /// - &ensp;**`=I.J.K`**&emsp;&mdash;&emsp;exactly the version I.J.K
210 /// - &ensp;**`=I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.J.0, <I.(J+1).0`
211 /// - &ensp;**`=I`**&emsp;&mdash;&emsp;equivalent to `>=I.0.0, <(I+1).0.0`
212 ///
213 /// # Op::Greater
214 /// - &ensp;**`>I.J.K`**
215 /// - &ensp;**`>I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.(J+1).0`
216 /// - &ensp;**`>I`**&emsp;&mdash;&emsp;equivalent to `>=(I+1).0.0`
217 ///
218 /// # Op::GreaterEq
219 /// - &ensp;**`>=I.J.K`**
220 /// - &ensp;**`>=I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.J.0`
221 /// - &ensp;**`>=I`**&emsp;&mdash;&emsp;equivalent to `>=I.0.0`
222 ///
223 /// # Op::Less
224 /// - &ensp;**`<I.J.K`**
225 /// - &ensp;**`<I.J`**&emsp;&mdash;&emsp;equivalent to `<I.J.0`
226 /// - &ensp;**`<I`**&emsp;&mdash;&emsp;equivalent to `<I.0.0`
227 ///
228 /// # Op::LessEq
229 /// - &ensp;**`<=I.J.K`**
230 /// - &ensp;**`<=I.J`**&emsp;&mdash;&emsp;equivalent to `<I.(J+1).0`
231 /// - &ensp;**`<=I`**&emsp;&mdash;&emsp;equivalent to `<(I+1).0.0`
232 ///
233 /// # Op::Tilde&emsp;("patch" updates)
234 /// *Tilde requirements allow the **patch** part of the semver version (the third number) to increase.*
235 /// - &ensp;**`~I.J.K`**&emsp;&mdash;&emsp;equivalent to `>=I.J.K, <I.(J+1).0`
236 /// - &ensp;**`~I.J`**&emsp;&mdash;&emsp;equivalent to `=I.J`
237 /// - &ensp;**`~I`**&emsp;&mdash;&emsp;equivalent to `=I`
238 ///
239 /// # Op::Caret&emsp;("compatible" updates)
240 /// *Caret requirements allow parts that are **right of the first nonzero** part of the semver version to increase.*
241 /// - &ensp;**`^I.J.K`**&ensp;(for I\>0)&emsp;&mdash;&emsp;equivalent to `>=I.J.K, <(I+1).0.0`
242 /// - &ensp;**`^0.J.K`**&ensp;(for J\>0)&emsp;&mdash;&emsp;equivalent to `>=0.J.K, <0.(J+1).0`
243 /// - &ensp;**`^0.0.K`**&emsp;&mdash;&emsp;equivalent to `=0.0.K`
244 /// - &ensp;**`^I.J`**&ensp;(for I\>0 or J\>0)&emsp;&mdash;&emsp;equivalent to `^I.J.0`
245 /// - &ensp;**`^0.0`**&emsp;&mdash;&emsp;equivalent to `=0.0`
246 /// - &ensp;**`^I`**&emsp;&mdash;&emsp;equivalent to `=I`
247 ///
248 /// # Op::Wildcard
249 /// - &ensp;**`I.J.*`**&emsp;&mdash;&emsp;equivalent to `=I.J`
250 /// - &ensp;**`I.*`**&ensp;or&ensp;**`I.*.*`**&emsp;&mdash;&emsp;equivalent to `=I`
251 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
252 #[cfg_attr(not(no_non_exhaustive), non_exhaustive)]
253 pub enum Op {
254     Exact,
255     Greater,
256     GreaterEq,
257     Less,
258     LessEq,
259     Tilde,
260     Caret,
261     Wildcard,
262 
263     #[cfg(no_non_exhaustive)] // rustc <1.40
264     #[doc(hidden)]
265     __NonExhaustive,
266 }
267 
268 /// Optional pre-release identifier on a version string. This comes after `-` in
269 /// a SemVer version, like `1.0.0-alpha.1`
270 ///
271 /// # Examples
272 ///
273 /// Some real world pre-release idioms drawn from crates.io:
274 ///
275 /// - **[mio]** <code>0.7.0-<b>alpha.1</b></code> &mdash; the most common style
276 ///   for numbering pre-releases.
277 ///
278 /// - **[pest]** <code>1.0.0-<b>beta.8</b></code>,&ensp;<code>1.0.0-<b>rc.0</b></code>
279 ///   &mdash; this crate makes a distinction between betas and release
280 ///   candidates.
281 ///
282 /// - **[sassers]** <code>0.11.0-<b>shitshow</b></code> &mdash; ???.
283 ///
284 /// - **[atomic-utils]** <code>0.0.0-<b>reserved</b></code> &mdash; a squatted
285 ///   crate name.
286 ///
287 /// [mio]: https://crates.io/crates/mio
288 /// [pest]: https://crates.io/crates/pest
289 /// [atomic-utils]: https://crates.io/crates/atomic-utils
290 /// [sassers]: https://crates.io/crates/sassers
291 ///
292 /// *Tip:* Be aware that if you are planning to number your own pre-releases,
293 /// you should prefer to separate the numeric part from any non-numeric
294 /// identifiers by using a dot in between. That is, prefer pre-releases
295 /// `alpha.1`, `alpha.2`, etc rather than `alpha1`, `alpha2` etc. The SemVer
296 /// spec's rule for pre-release precedence has special treatment of numeric
297 /// components in the pre-release string, but only if there are no non-digit
298 /// characters in the same dot-separated component. So you'd have `alpha.2` &lt;
299 /// `alpha.11` as intended, but `alpha11` &lt; `alpha2`.
300 ///
301 /// # Syntax
302 ///
303 /// Pre-release strings are a series of dot separated identifiers immediately
304 /// following the patch version. Identifiers must comprise only ASCII
305 /// alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-`. Identifiers must not be
306 /// empty. Numeric identifiers must not include leading zeros.
307 ///
308 /// # Total ordering
309 ///
310 /// Pre-releases have a total order defined by the SemVer spec. It uses
311 /// lexicographic ordering of dot-separated components. Identifiers consisting
312 /// of only digits are compared numerically. Otherwise, identifiers are compared
313 /// in ASCII sort order. Any numeric identifier is always less than any
314 /// non-numeric identifier.
315 ///
316 /// Example:&ensp;`alpha`&ensp;&lt;&ensp;`alpha.85`&ensp;&lt;&ensp;`alpha.90`&ensp;&lt;&ensp;`alpha.200`&ensp;&lt;&ensp;`alpha.0a`&ensp;&lt;&ensp;`alpha.1a0`&ensp;&lt;&ensp;`alpha.a`&ensp;&lt;&ensp;`beta`
317 #[derive(Default, Clone, Eq, PartialEq, Hash)]
318 pub struct Prerelease {
319     identifier: Identifier,
320 }
321 
322 /// Optional build metadata identifier. This comes after `+` in a SemVer
323 /// version, as in `0.8.1+zstd.1.5.0`.
324 ///
325 /// # Examples
326 ///
327 /// Some real world build metadata idioms drawn from crates.io:
328 ///
329 /// - **[libgit2-sys]** <code>0.12.20+<b>1.1.0</b></code> &mdash; for this
330 ///   crate, the build metadata indicates the version of the C libgit2 library
331 ///   that the Rust crate is built against.
332 ///
333 /// - **[mashup]** <code>0.1.13+<b>deprecated</b></code> &mdash; just the word
334 ///   "deprecated" for a crate that has been superseded by another. Eventually
335 ///   people will take notice of this in Cargo's build output where it lists the
336 ///   crates being compiled.
337 ///
338 /// - **[google-bigquery2]** <code>2.0.4+<b>20210327</b></code> &mdash; this
339 ///   library is automatically generated from an official API schema, and the
340 ///   build metadata indicates the date on which that schema was last captured.
341 ///
342 /// - **[fbthrift-git]** <code>0.0.6+<b>c7fcc0e</b></code> &mdash; this crate is
343 ///   published from snapshots of a big company monorepo. In monorepo
344 ///   development, there is no concept of versions, and all downstream code is
345 ///   just updated atomically in the same commit that breaking changes to a
346 ///   library are landed. Therefore for crates.io purposes, every published
347 ///   version must be assumed to be incompatible with the previous. The build
348 ///   metadata provides the source control hash of the snapshotted code.
349 ///
350 /// [libgit2-sys]: https://crates.io/crates/libgit2-sys
351 /// [mashup]: https://crates.io/crates/mashup
352 /// [google-bigquery2]: https://crates.io/crates/google-bigquery2
353 /// [fbthrift-git]: https://crates.io/crates/fbthrift-git
354 ///
355 /// # Syntax
356 ///
357 /// Build metadata is a series of dot separated identifiers immediately
358 /// following the patch or pre-release version. Identifiers must comprise only
359 /// ASCII alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-`. Identifiers must
360 /// not be empty. Leading zeros *are* allowed, unlike any other place in the
361 /// SemVer grammar.
362 ///
363 /// # Total ordering
364 ///
365 /// Build metadata is ignored in evaluating `VersionReq`; it plays no role in
366 /// whether a `Version` matches any one of the comparison operators.
367 ///
368 /// However for comparing build metadatas among one another, they do have a
369 /// total order which is determined by lexicographic ordering of dot-separated
370 /// components. Identifiers consisting of only digits are compared numerically.
371 /// Otherwise, identifiers are compared in ASCII sort order. Any numeric
372 /// identifier is always less than any non-numeric identifier.
373 ///
374 /// Example:&ensp;`demo`&ensp;&lt;&ensp;`demo.85`&ensp;&lt;&ensp;`demo.90`&ensp;&lt;&ensp;`demo.090`&ensp;&lt;&ensp;`demo.200`&ensp;&lt;&ensp;`demo.1a0`&ensp;&lt;&ensp;`demo.a`&ensp;&lt;&ensp;`memo`
375 #[derive(Default, Clone, Eq, PartialEq, Hash)]
376 pub struct BuildMetadata {
377     identifier: Identifier,
378 }
379 
380 impl Version {
381     /// Create `Version` with an empty pre-release and build metadata.
382     ///
383     /// Equivalent to:
384     ///
385     /// ```
386     /// # use semver::{BuildMetadata, Prerelease, Version};
387     /// #
388     /// # const fn new(major: u64, minor: u64, patch: u64) -> Version {
389     /// Version {
390     ///     major,
391     ///     minor,
392     ///     patch,
393     ///     pre: Prerelease::EMPTY,
394     ///     build: BuildMetadata::EMPTY,
395     /// }
396     /// # }
397     /// ```
new(major: u64, minor: u64, patch: u64) -> Self398     pub const fn new(major: u64, minor: u64, patch: u64) -> Self {
399         Version {
400             major,
401             minor,
402             patch,
403             pre: Prerelease::EMPTY,
404             build: BuildMetadata::EMPTY,
405         }
406     }
407 
408     /// Create `Version` by parsing from string representation.
409     ///
410     /// # Errors
411     ///
412     /// Possible reasons for the parse to fail include:
413     ///
414     /// - `1.0` &mdash; too few numeric components. A SemVer version must have
415     ///   exactly three. If you are looking at something that has fewer than
416     ///   three numbers in it, it's possible it is a `VersionReq` instead (with
417     ///   an implicit default `^` comparison operator).
418     ///
419     /// - `1.0.01` &mdash; a numeric component has a leading zero.
420     ///
421     /// - `1.0.unknown` &mdash; unexpected character in one of the components.
422     ///
423     /// - `1.0.0-` or `1.0.0+` &mdash; the pre-release or build metadata are
424     ///   indicated present but empty.
425     ///
426     /// - `1.0.0-alpha_123` &mdash; pre-release or build metadata have something
427     ///   outside the allowed characters, which are `0-9`, `A-Z`, `a-z`, `-`,
428     ///   and `.` (dot).
429     ///
430     /// - `23456789999999999999.0.0` &mdash; overflow of a u64.
parse(text: &str) -> Result<Self, Error>431     pub fn parse(text: &str) -> Result<Self, Error> {
432         Version::from_str(text)
433     }
434 
435     /// Compare the major, minor, patch, and pre-release value of two versions,
436     /// disregarding build metadata. Versions that differ only in build metadata
437     /// are considered equal. This comparison is what the SemVer spec refers to
438     /// as "precedence".
439     ///
440     /// # Example
441     ///
442     /// ```
443     /// use semver::Version;
444     ///
445     /// let mut versions = [
446     ///     "1.20.0+c144a98".parse::<Version>().unwrap(),
447     ///     "1.20.0".parse().unwrap(),
448     ///     "1.0.0".parse().unwrap(),
449     ///     "1.0.0-alpha".parse().unwrap(),
450     ///     "1.20.0+bc17664".parse().unwrap(),
451     /// ];
452     ///
453     /// // This is a stable sort, so it preserves the relative order of equal
454     /// // elements. The three 1.20.0 versions differ only in build metadata so
455     /// // they are not reordered relative to one another.
456     /// versions.sort_by(Version::cmp_precedence);
457     /// assert_eq!(versions, [
458     ///     "1.0.0-alpha".parse().unwrap(),
459     ///     "1.0.0".parse().unwrap(),
460     ///     "1.20.0+c144a98".parse().unwrap(),
461     ///     "1.20.0".parse().unwrap(),
462     ///     "1.20.0+bc17664".parse().unwrap(),
463     /// ]);
464     ///
465     /// // Totally order the versions, including comparing the build metadata.
466     /// versions.sort();
467     /// assert_eq!(versions, [
468     ///     "1.0.0-alpha".parse().unwrap(),
469     ///     "1.0.0".parse().unwrap(),
470     ///     "1.20.0".parse().unwrap(),
471     ///     "1.20.0+bc17664".parse().unwrap(),
472     ///     "1.20.0+c144a98".parse().unwrap(),
473     /// ]);
474     /// ```
cmp_precedence(&self, other: &Self) -> Ordering475     pub fn cmp_precedence(&self, other: &Self) -> Ordering {
476         Ord::cmp(
477             &(self.major, self.minor, self.patch, &self.pre),
478             &(other.major, other.minor, other.patch, &other.pre),
479         )
480     }
481 }
482 
483 impl VersionReq {
484     /// A `VersionReq` with no constraint on the version numbers it matches.
485     /// Equivalent to `VersionReq::parse("*").unwrap()`.
486     ///
487     /// In terms of comparators this is equivalent to `>=0.0.0`.
488     ///
489     /// Counterintuitively a `*` VersionReq does not match every possible
490     /// version number. In particular, in order for *any* `VersionReq` to match
491     /// a pre-release version, the `VersionReq` must contain at least one
492     /// `Comparator` that has an explicit major, minor, and patch version
493     /// identical to the pre-release being matched, and that has a nonempty
494     /// pre-release component. Since `*` is not written with an explicit major,
495     /// minor, and patch version, and does not contain a nonempty pre-release
496     /// component, it does not match any pre-release versions.
497     #[cfg(not(no_const_vec_new))] // rustc <1.39
498     pub const STAR: Self = VersionReq {
499         comparators: Vec::new(),
500     };
501 
502     /// Create `VersionReq` by parsing from string representation.
503     ///
504     /// # Errors
505     ///
506     /// Possible reasons for the parse to fail include:
507     ///
508     /// - `>a.b` &mdash; unexpected characters in the partial version.
509     ///
510     /// - `@1.0.0` &mdash; unrecognized comparison operator.
511     ///
512     /// - `^1.0.0, ` &mdash; unexpected end of input.
513     ///
514     /// - `>=1.0 <2.0` &mdash; missing comma between comparators.
515     ///
516     /// - `*.*` &mdash; unsupported wildcard syntax.
parse(text: &str) -> Result<Self, Error>517     pub fn parse(text: &str) -> Result<Self, Error> {
518         VersionReq::from_str(text)
519     }
520 
521     /// Evaluate whether the given `Version` satisfies the version requirement
522     /// described by `self`.
matches(&self, version: &Version) -> bool523     pub fn matches(&self, version: &Version) -> bool {
524         eval::matches_req(self, version)
525     }
526 }
527 
528 /// The default VersionReq is the same as [`VersionReq::STAR`].
529 #[cfg(not(no_const_vec_new))]
530 impl Default for VersionReq {
default() -> Self531     fn default() -> Self {
532         VersionReq::STAR
533     }
534 }
535 
536 impl Comparator {
parse(text: &str) -> Result<Self, Error>537     pub fn parse(text: &str) -> Result<Self, Error> {
538         Comparator::from_str(text)
539     }
540 
matches(&self, version: &Version) -> bool541     pub fn matches(&self, version: &Version) -> bool {
542         eval::matches_comparator(self, version)
543     }
544 }
545 
546 impl Prerelease {
547     pub const EMPTY: Self = Prerelease {
548         identifier: Identifier::empty(),
549     };
550 
new(text: &str) -> Result<Self, Error>551     pub fn new(text: &str) -> Result<Self, Error> {
552         Prerelease::from_str(text)
553     }
554 
as_str(&self) -> &str555     pub fn as_str(&self) -> &str {
556         self.identifier.as_str()
557     }
558 
is_empty(&self) -> bool559     pub fn is_empty(&self) -> bool {
560         self.identifier.is_empty()
561     }
562 }
563 
564 impl BuildMetadata {
565     pub const EMPTY: Self = BuildMetadata {
566         identifier: Identifier::empty(),
567     };
568 
new(text: &str) -> Result<Self, Error>569     pub fn new(text: &str) -> Result<Self, Error> {
570         BuildMetadata::from_str(text)
571     }
572 
as_str(&self) -> &str573     pub fn as_str(&self) -> &str {
574         self.identifier.as_str()
575     }
576 
is_empty(&self) -> bool577     pub fn is_empty(&self) -> bool {
578         self.identifier.is_empty()
579     }
580 }
581