uv_pep440/lib.rs
1//! A library for python version numbers and specifiers, implementing
2//! [PEP 440](https://peps.python.org/pep-0440)
3//!
4//! PEP 440 has a lot of unintuitive features, including:
5//!
6//! * An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower
7//! version (`1.0 <=2!0.1`)
8//! * post versions, which can be attached to both stable releases and pre-releases
9//! * dev versions, which can be attached to both table releases and pre-releases. When attached to a
10//! pre-release the dev version is ordered just below the normal pre-release, however when attached
11//! to a stable version, the dev version is sorted before a pre-releases
12//! * pre-release handling is a mess: "Pre-releases of any kind, including developmental releases,
13//! are implicitly excluded from all version specifiers, unless they are already present on the
14//! system, explicitly requested by the user, or if the only available version that satisfies
15//! the version specifier is a pre-release.". This means that we can't say whether a specifier
16//! matches without also looking at the environment
17//! * pre-release vs. pre-release incl. dev is fuzzy
18//! * local versions on top of all the others, which are added with a + and have implicitly typed
19//! string and number segments
20//! * no semver-caret (`^`), but a pseudo-semver tilde (`~=`)
21//! * ordering contradicts matching: We have e.g. `1.0+local > 1.0` when sorting,
22//! but `==1.0` matches `1.0+local`. While the ordering of versions itself is a total order
23//! the version matching needs to catch all sorts of special cases
24#![warn(missing_docs)]
25
26#[cfg(feature = "version-ranges")]
27pub use version_ranges::{
28 LowerBound, UpperBound, release_specifier_to_range, release_specifiers_to_ranges,
29};
30pub use {
31 version::{
32 BumpCommand, LocalSegment, LocalVersion, LocalVersionSlice, MIN_VERSION, Operator,
33 OperatorParseError, Prerelease, PrereleaseKind, Version, VersionParseError, VersionPattern,
34 VersionPatternParseError,
35 },
36 version_specifier::{
37 TildeVersionSpecifier, VersionSpecifier, VersionSpecifierBuildError, VersionSpecifiers,
38 VersionSpecifiersParseError,
39 },
40};
41
42mod version;
43mod version_specifier;
44
45#[cfg(feature = "version-ranges")]
46mod version_ranges;
47
48#[cfg(test)]
49mod tests {
50 use super::{Version, VersionSpecifier, VersionSpecifiers};
51 use std::str::FromStr;
52
53 #[test]
54 fn test_version() {
55 let version = Version::from_str("1.19").unwrap();
56 let version_specifier = VersionSpecifier::from_str("== 1.*").unwrap();
57 assert!(version_specifier.contains(&version));
58 let version_specifiers = VersionSpecifiers::from_str(">=1.16, <2.0").unwrap();
59 assert!(version_specifiers.contains(&version));
60 }
61}