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&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
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.3")]
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::items_after_statements,
74     clippy::match_bool,
75     clippy::missing_errors_doc,
76     clippy::must_use_candidate,
77     clippy::needless_doctest_main,
78     clippy::option_if_let_else,
79     clippy::ptr_as_ptr,
80     clippy::redundant_else,
81     clippy::similar_names,
82     clippy::unnested_or_patterns,
83     clippy::unseparated_literal_suffix,
84     clippy::wildcard_imports
85 )]
86 
87 #[cfg(not(no_alloc_crate))]
88 extern crate alloc;
89 
90 mod backport;
91 mod display;
92 mod error;
93 mod eval;
94 mod identifier;
95 mod impls;
96 mod parse;
97 
98 #[cfg(feature = "serde")]
99 mod serde;
100 
101 use crate::alloc::vec::Vec;
102 use crate::identifier::Identifier;
103 use core::str::FromStr;
104 
105 #[allow(unused_imports)]
106 use crate::backport::*;
107 
108 pub use crate::parse::Error;
109 
110 /// **SemVer version** as defined by <https://semver.org>.
111 ///
112 /// # Syntax
113 ///
114 /// - The major, minor, and patch numbers may be any integer 0 through u64::MAX.
115 ///   When representing a SemVer version as a string, each number is written as
116 ///   a base 10 integer. For example, `1.0.119`.
117 ///
118 /// - Leading zeros are forbidden in those positions. For example `1.01.00` is
119 ///   invalid as a SemVer version.
120 ///
121 /// - The pre-release identifier, if present, must conform to the syntax
122 ///   documented for [`Prerelease`].
123 ///
124 /// - The build metadata, if present, must conform to the syntax documented for
125 ///   [`BuildMetadata`].
126 ///
127 /// - Whitespace is not allowed anywhere in the version.
128 ///
129 /// # Total ordering
130 ///
131 /// Given any two SemVer versions, one is less than, greater than, or equal to
132 /// the other. Versions may be compared against one another using Rust's usual
133 /// comparison operators.
134 ///
135 /// - The major, minor, and patch number are compared numerically from left to
136 /// right, lexicographically ordered as a 3-tuple of integers. So for example
137 /// version `1.5.0` is less than version `1.19.0`, despite the fact that
138 /// "1.19.0" &lt; "1.5.0" as ASCIIbetically compared strings and 1.19 &lt; 1.5
139 /// as real numbers.
140 ///
141 /// - When major, minor, and patch are equal, a pre-release version is
142 ///   considered less than the ordinary release:&ensp;version `1.0.0-alpha.1` is
143 ///   less than version `1.0.0`.
144 ///
145 /// - Two pre-releases of the same major, minor, patch are compared by
146 ///   lexicographic ordering of dot-separated components of the pre-release
147 ///   string.
148 ///
149 ///   - Identifiers consisting of only digits are compared
150 ///     numerically:&ensp;`1.0.0-pre.8` is less than `1.0.0-pre.12`.
151 ///
152 ///   - Identifiers that contain a letter or hyphen are compared in ASCII sort
153 ///     order:&ensp;`1.0.0-pre12` is less than `1.0.0-pre8`.
154 ///
155 ///   - Any numeric identifier is always less than any non-numeric
156 ///     identifier:&ensp;`1.0.0-pre.1` is less than `1.0.0-pre.x`.
157 ///
158 /// 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`
159 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
160 pub struct Version {
161     pub major: u64,
162     pub minor: u64,
163     pub patch: u64,
164     pub pre: Prerelease,
165     pub build: BuildMetadata,
166 }
167 
168 /// **SemVer version requirement** describing the intersection of some version
169 /// comparators, such as `>=1.2.3, <1.8`.
170 ///
171 /// # Syntax
172 ///
173 /// - Either `*` (meaning "any"), or one or more comma-separated comparators.
174 ///
175 /// - A [`Comparator`] is an operator ([`Op`]) and a partial version, separated
176 ///   by optional whitespace. For example `>=1.0.0` or `>=1.0`.
177 ///
178 /// - Build metadata is syntactically permitted on the partial versions, but is
179 ///   completely ignored, as it's never relevant to whether any comparator
180 ///   matches a particular version.
181 ///
182 /// - Whitespace is permitted around commas and around operators. Whitespace is
183 ///   not permitted within a partial version, i.e. anywhere between the major
184 ///   version number and its minor, patch, pre-release, or build metadata.
185 #[derive(Default, Clone, Eq, PartialEq, Hash, Debug)]
186 pub struct VersionReq {
187     pub comparators: Vec<Comparator>,
188 }
189 
190 /// A pair of comparison operator and partial version, such as `>=1.2`. Forms
191 /// one piece of a VersionReq.
192 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
193 pub struct Comparator {
194     pub op: Op,
195     pub major: u64,
196     pub minor: Option<u64>,
197     /// Patch is only allowed if minor is Some.
198     pub patch: Option<u64>,
199     /// Non-empty pre-release is only allowed if patch is Some.
200     pub pre: Prerelease,
201 }
202 
203 /// SemVer comparison operator: `=`, `>`, `>=`, `<`, `<=`, `~`, `^`, `*`.
204 ///
205 /// # Op::Exact
206 /// - &ensp;**`=I.J.K`**&emsp;&mdash;&emsp;exactly the version I.J.K
207 /// - &ensp;**`=I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.J.0, <I.(J+1).0`
208 /// - &ensp;**`=I`**&emsp;&mdash;&emsp;equivalent to `>=I.0.0, <(I+1).0.0`
209 ///
210 /// # Op::Greater
211 /// - &ensp;**`>I.J.K`**
212 /// - &ensp;**`>I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.(J+1).0`
213 /// - &ensp;**`>I`**&emsp;&mdash;&emsp;equivalent to `>=(I+1).0.0`
214 ///
215 /// # Op::GreaterEq
216 /// - &ensp;**`>=I.J.K`**
217 /// - &ensp;**`>=I.J`**&emsp;&mdash;&emsp;equivalent to `>=I.J.0`
218 /// - &ensp;**`>=I`**&emsp;&mdash;&emsp;equivalent to `>=I.0.0`
219 ///
220 /// # Op::Less
221 /// - &ensp;**`<I.J.K`**
222 /// - &ensp;**`<I.J`**&emsp;&mdash;&emsp;equivalent to `<I.J.0`
223 /// - &ensp;**`<I`**&emsp;&mdash;&emsp;equivalent to `<I.0.0`
224 ///
225 /// # Op::LessEq
226 /// - &ensp;**`<=I.J.K`**
227 /// - &ensp;**`<=I.J`**&emsp;&mdash;&emsp;equivalent to `<I.(J+1).0`
228 /// - &ensp;**`<=I`**&emsp;&mdash;&emsp;equivalent to `<(I+1).0.0`
229 ///
230 /// # Op::Tilde&emsp;("patch" updates)
231 /// *Tilde requirements allow the **patch** part of the semver version (the third number) to increase.*
232 /// - &ensp;**`~I.J.K`**&emsp;&mdash;&emsp;equivalent to `>=I.J.K, <I.(J+1).0`
233 /// - &ensp;**`~I.J`**&emsp;&mdash;&emsp;equivalent to `=I.J`
234 /// - &ensp;**`~I`**&emsp;&mdash;&emsp;equivalent to `=I`
235 ///
236 /// # Op::Caret&emsp;("compatible" updates)
237 /// *Caret requirements allow parts that are **right of the first nonzero** part of the semver version to increase.*
238 /// - &ensp;**`^I.J.K`**&ensp;(for I\>0)&emsp;&mdash;&emsp;equivalent to `>=I.J.K, <(I+1).0.0`
239 /// - &ensp;**`^0.J.K`**&ensp;(for J\>0)&emsp;&mdash;&emsp;equivalent to `>=0.J.K, <0.(J+1).0`
240 /// - &ensp;**`^0.0.K`**&emsp;&mdash;&emsp;equivalent to `=0.0.K`
241 /// - &ensp;**`^I.J`**&ensp;(for I\>0 or J\>0)&emsp;&mdash;&emsp;equivalent to `^I.J.0`
242 /// - &ensp;**`^0.0`**&emsp;&mdash;&emsp;equivalent to `=0.0`
243 /// - &ensp;**`^I`**&emsp;&mdash;&emsp;equivalent to `=I`
244 ///
245 /// # Op::Wildcard
246 /// - &ensp;**`I.J.*`**&emsp;&mdash;&emsp;equivalent to `=I.J`
247 /// - &ensp;**`I.*`**&ensp;or&ensp;**`I.*.*`**&emsp;&mdash;&emsp;equivalent to `=I`
248 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
249 #[cfg_attr(not(no_non_exhaustive), non_exhaustive)]
250 pub enum Op {
251     Exact,
252     Greater,
253     GreaterEq,
254     Less,
255     LessEq,
256     Tilde,
257     Caret,
258     Wildcard,
259 
260     #[cfg(no_non_exhaustive)] // rustc <1.40
261     #[doc(hidden)]
262     __NonExhaustive,
263 }
264 
265 /// Optional pre-release identifier on a version string. This comes after `-` in
266 /// a SemVer version, like `1.0.0-alpha.1`
267 ///
268 /// # Examples
269 ///
270 /// Some real world pre-release idioms drawn from crates.io:
271 ///
272 /// - **[mio]** <code>0.7.0-<b>alpha.1</b></code> &mdash; the most common style
273 ///   for numbering pre-releases.
274 ///
275 /// - **[pest]** <code>1.0.0-<b>beta.8</b></code>,&ensp;<code>1.0.0-<b>rc.0</b></code>
276 ///   &mdash; this crate makes a distinction between betas and release
277 ///   candidates.
278 ///
279 /// - **[sassers]** <code>0.11.0-<b>shitshow</b></code> &mdash; ???.
280 ///
281 /// - **[atomic-utils]** <code>0.0.0-<b>reserved</b></code> &mdash; a squatted
282 ///   crate name.
283 ///
284 /// [mio]: https://crates.io/crates/mio
285 /// [pest]: https://crates.io/crates/pest
286 /// [atomic-utils]: https://crates.io/crates/atomic-utils
287 /// [sassers]: https://crates.io/crates/sassers
288 ///
289 /// *Tip:* Be aware that if you are planning to number your own pre-releases,
290 /// you should prefer to separate the numeric part from any non-numeric
291 /// identifiers by using a dot in between. That is, prefer pre-releases
292 /// `alpha.1`, `alpha.2`, etc rather than `alpha1`, `alpha2` etc. The SemVer
293 /// spec's rule for pre-release precedence has special treatment of numeric
294 /// components in the pre-release string, but only if there are no non-digit
295 /// characters in the same dot-separated component. So you'd have `alpha.2` &lt;
296 /// `alpha.11` as intended, but `alpha11` &lt; `alpha2`.
297 ///
298 /// # Syntax
299 ///
300 /// Pre-release strings are a series of dot separated identifiers immediately
301 /// following the patch version. Identifiers must comprise only ASCII
302 /// alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-`. Identifiers must not be
303 /// empty. Numeric identifiers must not include leading zeros.
304 ///
305 /// # Total ordering
306 ///
307 /// Pre-releases have a total order defined by the SemVer spec. It uses
308 /// lexicographic ordering of dot-separated components. Identifiers consisting
309 /// of only digits are compared numerically. Otherwise, identifiers are compared
310 /// in ASCII sort order. Any numeric identifier is always less than any
311 /// non-numeric identifier.
312 ///
313 /// 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`
314 #[derive(Default, Clone, Eq, PartialEq, Hash)]
315 pub struct Prerelease {
316     identifier: Identifier,
317 }
318 
319 /// Optional build metadata identifier. This comes after `+` in a SemVer
320 /// verison, as in `0.8.1+zstd.1.5.0`.
321 ///
322 /// # Examples
323 ///
324 /// Some real world build metadata idioms drawn from crates.io:
325 ///
326 /// - **[libgit2-sys]** <code>0.12.20+<b>1.1.0</b></code> &mdash; for this
327 ///   crate, the build metadata indicates the version of the C libgit2 library
328 ///   that the Rust crate is built against.
329 ///
330 /// - **[mashup]** <code>0.1.13+<b>deprecated</b></code> &mdash; just the word
331 ///   "deprecated" for a crate that has been superseded by another. Eventually
332 ///   people will take notice of this in Cargo's build output where it lists the
333 ///   crates being compiled.
334 ///
335 /// - **[google-bigquery2]** <code>2.0.4+<b>20210327</b></code> &mdash; this
336 ///   library is automatically generated from an official API schema, and the
337 ///   build metadata indicates the date on which that schema was last captured.
338 ///
339 /// - **[fbthrift-git]** <code>0.0.6+<b>c7fcc0e</b></code> &mdash; this crate is
340 ///   published from snapshots of a big company monorepo. In monorepo
341 ///   development, there is no concept of versions, and all downstream code is
342 ///   just updated atomically in the same commit that breaking changes to a
343 ///   library are landed. Therefore for crates.io purposes, every published
344 ///   version must be assumed to be incompatible with the previous. The build
345 ///   metadata provides the source control hash of the snapshotted code.
346 ///
347 /// [libgit2-sys]: https://crates.io/crates/libgit2-sys
348 /// [mashup]: https://crates.io/crates/mashup
349 /// [google-bigquery2]: https://crates.io/crates/google-bigquery2
350 /// [fbthrift-git]: https://crates.io/crates/fbthrift-git
351 ///
352 /// # Syntax
353 ///
354 /// Build metadata is a series of dot separated identifiers immediately
355 /// following the patch or pre-release version. Identifiers must comprise only
356 /// ASCII alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-`. Identifiers must
357 /// not be empty. Leading zeros *are* allowed, unlike any other place in the
358 /// SemVer grammar.
359 ///
360 /// # Total ordering
361 ///
362 /// Build metadata is ignored in evaluating `VersionReq`; it plays no role in
363 /// whether a `Version` matches any one of the comparison operators.
364 ///
365 /// However for comparing build metadatas among one another, they do have a
366 /// total order which is determined by lexicographic ordering of dot-separated
367 /// components. Identifiers consisting of only digits are compared numerically.
368 /// Otherwise, identifiers are compared in ASCII sort order. Any numeric
369 /// identifier is always less than any non-numeric identifier.
370 ///
371 /// 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`
372 #[derive(Default, Clone, Eq, PartialEq, Hash)]
373 pub struct BuildMetadata {
374     identifier: Identifier,
375 }
376 
377 impl Version {
378     /// Create `Version` with an empty pre-release and build metadata.
379     ///
380     /// Equivalent to:
381     ///
382     /// ```
383     /// # use semver::{BuildMetadata, Prerelease, Version};
384     /// #
385     /// # const fn new(major: u64, minor: u64, patch: u64) -> Version {
386     /// Version {
387     ///     major,
388     ///     minor,
389     ///     patch,
390     ///     pre: Prerelease::EMPTY,
391     ///     build: BuildMetadata::EMPTY,
392     /// }
393     /// # }
394     /// ```
new(major: u64, minor: u64, patch: u64) -> Self395     pub const fn new(major: u64, minor: u64, patch: u64) -> Self {
396         Version {
397             major,
398             minor,
399             patch,
400             pre: Prerelease::EMPTY,
401             build: BuildMetadata::EMPTY,
402         }
403     }
404 
405     /// Create `Version` by parsing from string representation.
406     ///
407     /// # Errors
408     ///
409     /// Possible reasons for the parse to fail include:
410     ///
411     /// - `1.0` &mdash; too few numeric components. A SemVer version must have
412     ///   exactly three. If you are looking at something that has fewer than
413     ///   three numbers in it, it's possible it is a `VersionReq` instead (with
414     ///   an implicit default `^` comparison operator).
415     ///
416     /// - `1.0.01` &mdash; a numeric component has a leading zero.
417     ///
418     /// - `1.0.unknown` &mdash; unexpected character in one of the components.
419     ///
420     /// - `1.0.0-` or `1.0.0+` &mdash; the pre-release or build metadata are
421     ///   indicated present but empty.
422     ///
423     /// - `1.0.0-alpha_123` &mdash; pre-release or build metadata have something
424     ///   outside the allowed characters, which are `0-9`, `A-Z`, `a-z`, `-`,
425     ///   and `.` (dot).
426     ///
427     /// - `23456789999999999999.0.0` &mdash; overflow of a u64.
parse(text: &str) -> Result<Self, Error>428     pub fn parse(text: &str) -> Result<Self, Error> {
429         Version::from_str(text)
430     }
431 }
432 
433 impl VersionReq {
434     /// A `VersionReq` with no constraint on the version numbers it matches.
435     /// Equivalent to `VersionReq::parse("*").unwrap()`.
436     ///
437     /// In terms of comparators this is equivalent to `>=0.0.0`.
438     ///
439     /// Counterintuitively a `*` VersionReq does not match every possible
440     /// version number. In particular, in order for *any* `VersionReq` to match
441     /// a pre-release version, the `VersionReq` must contain at least one
442     /// `Comparator` that has an explicit major, minor, and patch version
443     /// identical to the pre-release being matched, and that has a nonempty
444     /// pre-release component. Since `*` is not written with an explicit major,
445     /// minor, and patch version, and does not contain a nonempty pre-release
446     /// component, it does not match any pre-release versions.
447     #[cfg(not(no_const_vec_new))] // rustc <1.39
448     pub const STAR: Self = VersionReq {
449         comparators: Vec::new(),
450     };
451 
452     /// Create `VersionReq` by parsing from string representation.
453     ///
454     /// # Errors
455     ///
456     /// Possible reasons for the parse to fail include:
457     ///
458     /// - `>a.b` &mdash; unexpected characters in the partial version.
459     ///
460     /// - `@1.0.0` &mdash; unrecognized comparison operator.
461     ///
462     /// - `^1.0.0, ` &mdash; unexpected end of input.
463     ///
464     /// - `>=1.0 <2.0` &mdash; missing comma between comparators.
465     ///
466     /// - `*.*` &mdash; unsupported wildcard syntax.
parse(text: &str) -> Result<Self, Error>467     pub fn parse(text: &str) -> Result<Self, Error> {
468         VersionReq::from_str(text)
469     }
470 
471     /// Evaluate whether the given `Version` satisfies the version requirement
472     /// described by `self`.
matches(&self, version: &Version) -> bool473     pub fn matches(&self, version: &Version) -> bool {
474         eval::matches_req(self, version)
475     }
476 }
477 
478 impl Comparator {
parse(text: &str) -> Result<Self, Error>479     pub fn parse(text: &str) -> Result<Self, Error> {
480         Comparator::from_str(text)
481     }
482 
matches(&self, version: &Version) -> bool483     pub fn matches(&self, version: &Version) -> bool {
484         eval::matches_comparator(self, version)
485     }
486 }
487 
488 impl Prerelease {
489     pub const EMPTY: Self = Prerelease {
490         identifier: Identifier::empty(),
491     };
492 
new(text: &str) -> Result<Self, Error>493     pub fn new(text: &str) -> Result<Self, Error> {
494         Prerelease::from_str(text)
495     }
496 
as_str(&self) -> &str497     pub fn as_str(&self) -> &str {
498         self.identifier.as_str()
499     }
500 
is_empty(&self) -> bool501     pub fn is_empty(&self) -> bool {
502         self.identifier.is_empty()
503     }
504 }
505 
506 impl BuildMetadata {
507     pub const EMPTY: Self = BuildMetadata {
508         identifier: Identifier::empty(),
509     };
510 
new(text: &str) -> Result<Self, Error>511     pub fn new(text: &str) -> Result<Self, Error> {
512         BuildMetadata::from_str(text)
513     }
514 
as_str(&self) -> &str515     pub fn as_str(&self) -> &str {
516         self.identifier.as_str()
517     }
518 
is_empty(&self) -> bool519     pub fn is_empty(&self) -> bool {
520         self.identifier.is_empty()
521     }
522 }
523