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