### Standard Semver Dependency Setup Source: https://github.com/dtolnay/semver/blob/master/_autodocs/README.md Include this in your Cargo.toml for the standard setup, which enables all features and supports the std library. ```toml [dependencies] semver = "1.0" ``` -------------------------------- ### Semver Dependency Setup with Serialization Source: https://github.com/dtolnay/semver/blob/master/_autodocs/README.md Enable JSON serialization and deserialization by adding the 'serde' feature to your semver dependency. ```toml [dependencies] semver = { version = "1.0", features = ["serde"] } ``` -------------------------------- ### Example Usage of BuildMetadata::EMPTY Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Demonstrates how to initialize a Version with BuildMetadata::EMPTY and assert that its build metadata is empty. ```rust use semver::{BuildMetadata, Version}; let version = Version { major: 1, minor: 0, patch: 0, pre: Default::default(), build: BuildMetadata::EMPTY, }; assert!(version.build.is_empty()); ``` -------------------------------- ### Version Parsing Flow Example Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Illustrates the step-by-step process of parsing a version string, showing how numeric identifiers, prerelease, and build metadata are extracted. ```rust "1.2.3-alpha.1+build" → numeric_identifier() → (1, ".2.3-alpha.1+build") dot() → ".2.3-alpha.1+build" numeric_identifier() → (2, ".3-alpha.1+build") dot() → ".3-alpha.1+build" numeric_identifier() → (3, "-alpha.1+build") [optional: strip_prefix('-')] prerelease_identifier() → Prerelease("alpha.1"), "+build" [optional: strip_prefix('+')] build_identifier() → BuildMetadata("build"), "" [final check: empty remaining] → Version { major: 1, minor: 2, patch: 3, pre, build } ``` -------------------------------- ### VersionReq::STAR Usage Example Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/versionreq.md Demonstrates matching various versions against the VersionReq::STAR requirement. Note that pre-releases are not matched by STAR. ```rust use semver::{Version, VersionReq}; let star = VersionReq::STAR; assert!(star.matches(&Version::parse("1.0.0").unwrap())); assert!(star.matches(&Version::parse("0.0.0").unwrap())); assert!(star.matches(&Version::new(999, 999, 999))); // Pre-releases are NOT matched by STAR assert!(!star.matches(&Version::parse("1.0.0-alpha").unwrap())); ``` -------------------------------- ### Example Usage of BuildMetadata::as_str Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Demonstrates retrieving the string representation of parsed build metadata and verifying that BuildMetadata::EMPTY yields an empty string. ```rust use semver::BuildMetadata; let build = BuildMetadata::new("001").unwrap(); assert_eq!(build.as_str(), "001"); assert_eq!(BuildMetadata::EMPTY.as_str(), ""); ``` -------------------------------- ### Serde Serialization and Deserialization Example Source: https://github.com/dtolnay/semver/blob/master/_autodocs/configuration.md Demonstrates serializing a `Version` to a JSON string and deserializing it back. This requires the `serde` feature to be enabled. ```rust use semver::Version; use serde::{Serialize, Deserialize}; let version = Version::parse("1.2.3").unwrap(); let json = serde_json::to_string(&version).unwrap(); assert_eq!(json, r"""1.2.3""""); let deserialized: Version = serde_json::from_str(r"""1.2.3"""").unwrap(); assert_eq!(deserialized, version); ``` -------------------------------- ### Example Usage of BuildMetadata::new Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Shows successful parsing of valid build metadata strings, including those with leading zeros, and demonstrates error cases for invalid formats like empty segments or invalid characters. ```rust use semver::BuildMetadata; let build = BuildMetadata::new("20130313144700").unwrap(); assert_eq!(build.as_str(), "20130313144700"); let build = BuildMetadata::new("zstd.1.5.0").unwrap(); assert_eq!(build.as_str(), "zstd.1.5.0"); let build = BuildMetadata::new("001").unwrap(); // Leading zeros allowed assert_eq!(build.as_str(), "001"); // Invalid build metadata assert!(BuildMetadata::new("..").is_err()); // Empty segments assert!(BuildMetadata::new("zstd_1").is_err()); // Invalid character (underscore) ``` -------------------------------- ### Operator Quick Reference Table Source: https://github.com/dtolnay/semver/blob/master/_autodocs/REFERENCE.md Provides a quick reference for semantic versioning operators, their syntax, meaning, and examples. ```markdown | Op | Syntax | Meaning | |----|--------|---------| | **Exact** | `=` or omitted | Exact match or range for partial | | **GreaterEq** | `>=` | At least this version | | **Greater** | `>` | Strictly greater | | **LessEq** | `<=` | At most this version | | **Less** | `<` | Strictly less | | **Tilde** | `~` | Patch-compatible | | **Caret** | `^` | Compatible (right of first nonzero) | | **Wildcard** | `*` or `x` | Any version at this precision | ``` -------------------------------- ### Example Usage of BuildMetadata::is_empty Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Verifies that BuildMetadata::EMPTY returns true for is_empty, and a non-empty parsed BuildMetadata returns false. ```rust use semver::BuildMetadata; assert!(BuildMetadata::EMPTY.is_empty()); assert!(!BuildMetadata::new("20130313144700").unwrap().is_empty()); ``` -------------------------------- ### Unrecognized Operator in VersionReq Parse Source: https://github.com/dtolnay/semver/blob/master/_autodocs/errors.md Use when a character that is not a recognized operator appears at the start of a version requirement string. ```rust use semver::VersionReq; assert!(VersionReq::parse("@1.0.0").is_err()); // @ is not an operator assert!(VersionReq::parse("!1.0.0").is_err()); // ! is not an operator ``` -------------------------------- ### Create a Version with `Version::new` Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/version.md Use `Version::new` to create a Version with specified major, minor, and patch numbers. Pre-release and build metadata are automatically initialized as empty. ```rust use semver::Version; let version = Version::new(1, 2, 3); assert_eq!(version.major, 1); assert_eq!(version.minor, 2); assert_eq!(version.patch, 3); assert!(version.pre.is_empty()); assert!(version.build.is_empty()); ``` -------------------------------- ### Version Memory Layout (64-bit) Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Illustrates the memory layout of the `Version` struct on a 64-bit system, showing the size and offset of each field. Note that `Option` has no niche waste. ```text Version { major: u64 [8 bytes] offset 0 minor: u64 [8 bytes] offset 8 patch: u64 [8 bytes] offset 16 pre: Prerelease [8 bytes] offset 24 (Identifier) build: BuildMetadata[8 bytes] offset 32 (Identifier) } Total: 40 bytes Alignment: 8 bytes ``` -------------------------------- ### Compare Versions with Build Metadata Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Demonstrates the ordering of versions when build metadata is present. Note that this ordering is for direct comparison (e.g., '<', '>') and not for precedence checks (e.g., VersionReq matching). ```rust use semver::Version; use std::cmp::Ordering; let v1 = Version::parse("1.0.0").unwrap(); let v2 = Version::parse("1.0.0+001").unwrap(); let v3 = Version::parse("1.0.0+1").unwrap(); let v4 = Version::parse("1.0.0+20130313144700").unwrap(); // Build metadata ordering (for total ordering, not precedence) assert!(v1 < v2); // no build < with build assert!(v2 < v3); // 001 < 1 (by value, then length) assert!(v3 < v4); // 1 < 20130313144700 // But for precedence (VersionReq matching), build is ignored: assert_eq!(v1.cmp_precedence(&v2), Ordering::Equal); assert_eq!(v1.cmp_precedence(&v3), Ordering::Equal); ``` -------------------------------- ### Prerelease: Leading Zero in Numeric Identifier Errors Source: https://github.com/dtolnay/semver/blob/master/_autodocs/errors.md This error is triggered when a numeric component of a pre-release identifier starts with a zero followed by other digits. A single zero is permitted. ```rust use semver::Prerelease; assert!(Prerelease::new("alpha.01").is_err()); assert!(Prerelease::new("01").is_err()); ``` -------------------------------- ### Comparing SemVer Prereleases in Rust Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/prerelease.md Demonstrates the ordering rules for SemVer pre-releases using the `semver` crate in Rust. Shows comparisons between numeric and non-numeric identifiers, longer and shorter pre-releases, and release versions. ```rust use semver::Prerelease; use std::cmp::Ordering; let alpha = Prerelease::new("alpha").unwrap(); let alpha1 = Prerelease::new("alpha.1").unwrap(); let alpha10 = Prerelease::new("alpha.10").unwrap(); let beta = Prerelease::new("beta").unwrap(); let release = Prerelease::EMPTY; // Numeric components compared numerically assert!(alpha1 < alpha10); // 1 < 10 // Longer pre-release greater than shorter assert!(alpha < alpha1); // alpha < alpha.1 // Non-numeric compared lexically assert!(alpha < beta); // "alpha" < "beta" // Release greater than all pre-releases assert!(beta < release); ``` -------------------------------- ### Handle Leading Zero Error in Version Parsing Source: https://github.com/dtolnay/semver/blob/master/_autodocs/errors.md This error occurs when a numeric component (major, minor, or patch) starts with a '0' followed by other digits. A single '0' is permitted. ```rust use semver::Version; assert!(Version::parse("01.0.0").is_err()); // Leading zero in major assert!(Version::parse("1.00.0").is_err()); // Leading zero in minor assert!(Version::parse("1.0.01").is_err()); // Leading zero in patch ``` -------------------------------- ### Prerelease/BuildMetadata Memory Layout (64-bit) Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Details the memory layout of `Prerelease` and `BuildMetadata` (as `Identifier`) on a 64-bit system, highlighting the use of a pointer for storage. ```text Identifier { head: NonNull [8 bytes] offset 0 tail: [u8; 0] [0 bytes] offset 8 (empty on 64-bit) } Total: 8 bytes Alignment: 8 bytes Option is also 40 bytes (no niche waste) ``` -------------------------------- ### Semver Matching Flow Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Illustrates the step-by-step process of how a VersionReq is matched against a Version, detailing the evaluation of comparators and special pre-release handling. ```rust VersionReq::matches(&version: &Version) → bool ├─ eval::matches_req(&req, &version) │ ├─ For each comparator in req.comparators: │ │ └─ eval::matches_impl(&comparator, &version) │ │ ├─ Match by operator: │ │ │ ├─ Op::Exact → matches_exact() │ │ │ ├─ Op::Greater → matches_greater() │ │ │ ├─ Op::GreaterEq → matches_exact() || matches_greater() │ │ │ ├─ Op::Less → matches_less() │ │ │ ├─ Op::LessEq → matches_exact() || matches_less() │ │ │ ├─ Op::Tilde → matches_tilde() │ │ │ ├─ Op::Caret → matches_caret() │ │ │ └─ Op::Wildcard → matches_exact() │ │ └─ Return: bool │ │ │ └─ All comparators matched? → return true else continue │ └─ Special pre-release handling: └─ If version.pre is not empty: └─ Must have at least one comparator where: major == version.major AND minor == Some(version.minor) AND patch == Some(version.patch) AND comparator.pre is not empty ``` -------------------------------- ### Handle Semver Pre-releases Source: https://github.com/dtolnay/semver/blob/master/_autodocs/REFERENCE.md Illustrates how VersionReq matching behaves with pre-release versions. Generic requirements do not match pre-releases, but explicit pre-release requirements do. ```rust use semver::{Version, VersionReq}; let req_strict = VersionReq::parse(">=1.0.0")?; let prerelease = Version::parse("1.0.0-alpha")?; // Pre-releases NOT matched by generic requirements assert!(!req_strict.matches(&prerelease)); // But DO match explicit pre-release requirements let req_pre = VersionReq::parse(">=1.0.0-alpha")?; assert!(req_pre.matches(&prerelease)); ``` -------------------------------- ### Version::new Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/version.md Creates a new Version instance with the specified major, minor, and patch numbers. Pre-release and build metadata are initialized as empty. ```APIDOC ## Version::new ### Description Create a `Version` with empty pre-release and build metadata. ### Signature ```rust pub const fn new(major: u64, minor: u64, patch: u64) -> Self ``` ### Parameters #### Path Parameters - **major** (u64) - Required - Major version number - **minor** (u64) - Required - Minor version number - **patch** (u64) - Required - Patch version number ### Return Type Returns a `Version` with the specified major, minor, and patch versions. The pre-release and build metadata fields are automatically set to empty. ### Example ```rust use semver::Version; let version = Version::new(1, 2, 3); assert_eq!(version.major, 1); assert_eq!(version.minor, 2); assert_eq!(version.patch, 3); assert!(version.pre.is_empty()); assert!(version.build.is_empty()); ``` ``` -------------------------------- ### Constructing SemVer Components Source: https://github.com/dtolnay/semver/blob/master/_autodocs/INDEX.md Shows how to construct SemVer components programmatically. Useful for creating default or specific version requirements and metadata. ```rust Version::new(1, 2, 3) → Version VersionReq::STAR → VersionReq Prerelease::EMPTY → Prerelease BuildMetadata::EMPTY → BuildMetadata ``` -------------------------------- ### Creating a Version with Prerelease::EMPTY Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/prerelease.md Demonstrates how to create a Version struct with an empty pre-release identifier using Prerelease::EMPTY. ```rust use semver::{Prerelease, Version}; let version = Version { major: 1, minor: 0, patch: 0, pre: Prerelease::EMPTY, build: Default::default(), }; assert!(version.pre.is_empty()); ``` -------------------------------- ### Prerelease::new Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/prerelease.md Creates a Prerelease instance by parsing a string representation. ```APIDOC ## Prerelease::new ### Description Create a `Prerelease` by parsing from a string representation. ### Method ```rust pub fn new(text: &str) -> Result ``` ### Parameters #### Path Parameters - **text** (str) - Required - Pre-release identifier string without the leading hyphen (e.g., "alpha.1" or "rc.2") ### Return Type Returns `Result`. On success, returns a parsed `Prerelease`. On failure, returns an `Error` describing the parsing failure. ### Syntax Pre-release identifiers are dot-separated components, each of which: - Contains only ASCII alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-` - Must not be empty (no consecutive dots) - Numeric components must not have leading zeros ### Errors - **Empty segment**: Contains consecutive dots or ends with a dot - **Invalid characters**: Contains characters outside the allowed set - **Leading zeros**: A numeric component has a leading zero (e.g., "01") ### Example ```rust use semver::Prerelease; let pre = Prerelease::new("alpha.1").unwrap(); assert_eq!(pre.as_str(), "alpha.1"); let pre = Prerelease::new("rc.2").unwrap(); assert_eq!(pre.as_str(), "rc.2"); // Invalid pre-releases assert!(Prerelease::new("alpha.01").is_err()); // Leading zero assert!(Prerelease::new("alpha..1").is_err()); // Empty segment assert!(Prerelease::new("alpha_1").is_err()); // Invalid character (underscore) ``` ``` -------------------------------- ### Configure docs.rs Documentation Source: https://github.com/dtolnay/semver/blob/master/_autodocs/configuration.md This configuration snippet for `Cargo.toml` optimizes documentation generation on docs.rs by enabling the `serde` feature and setting up rustdoc arguments for better linking and external crate referencing. ```toml [package.metadata.docs.rs] features = ["serde"] targets = ["x86_64-unknown-linux-gnu"] rustdoc-args = [ "--generate-link-to-definition", "--generate-macro-expansion", "--extern-html-root-url=core=https://doc.rust-lang.org", "--extern-html-root-url=alloc=https://doc.rust-lang.org", "--extern-html-root-url=std=https://doc.rust-lang.org", ] ``` -------------------------------- ### BuildMetadata::as_str Method Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Returns the build metadata as a string slice. For BuildMetadata::EMPTY, it returns an empty string. ```rust pub fn as_str(&self) -> &str ``` -------------------------------- ### Parse and Compare Semver Versions Source: https://github.com/dtolnay/semver/blob/master/_autodocs/REFERENCE.md Demonstrates parsing version strings into Version objects and comparing them using total ordering and precedence. ```rust use semver::Version; let v1 = Version::parse("1.2.3")?; let v2 = Version::parse("1.3.0")?; assert!(v1 < v2); // Uses total ordering assert_eq!( v1.cmp_precedence(&v2), std::cmp::Ordering::Less ); // Same for precedence in this case ``` -------------------------------- ### Handle Pre-release Versions Source: https://github.com/dtolnay/semver/blob/master/_autodocs/README.md Shows how to parse a version with pre-release identifiers and access its pre-release information. Asserts that the pre-release part is not empty and matches the expected string. ```rust use semver::Version; let prerelease = Version::parse("1.0.0-alpha.1")?; assert!(!prerelease.pre.is_empty()); assert_eq!(prerelease.pre.as_str(), "alpha.1"); ``` -------------------------------- ### Constructing Version Objects Source: https://github.com/dtolnay/semver/blob/master/_autodocs/INDEX.md Create new Version, VersionReq, Prerelease, and BuildMetadata objects. ```APIDOC ## Construction ```rust Version::new(1, 2, 3) → Version VersionReq::STAR → VersionReq Prerelease::EMPTY → Prerelease BuildMetadata::EMPTY → BuildMetadata ``` ``` -------------------------------- ### Minimal Configuration for no_std Environments Source: https://github.com/dtolnay/semver/blob/master/_autodocs/configuration.md This TOML snippet shows the minimal configuration required for `no_std` environments, disabling default features to exclude standard library dependencies. ```toml # Cargo.toml [dependencies] semver = { version = "1.0", default-features = false } ``` -------------------------------- ### Compare Version Precedence and Ordering Source: https://github.com/dtolnay/semver/blob/master/_autodocs/README.md Illustrates the difference between version precedence (ignoring build metadata) and total ordering (including build metadata) using `cmp_precedence` and standard comparison operators. ```rust use semver::Version; use std::cmp::Ordering; let v1 = Version::parse("1.0.0+build1")?; let v2 = Version::parse("1.0.0+build2")?; // Precedence ignores build metadata assert_eq!(v1.cmp_precedence(&v2), Ordering::Equal); // Total ordering includes build metadata assert!(v1 < v2); ``` -------------------------------- ### Match Pre-release Versions Source: https://github.com/dtolnay/semver/blob/master/_autodocs/README.md Demonstrates how pre-release versions are handled by semver requirements. Generic ranges do not match pre-releases, but explicit pre-release requirements do. ```rust use semver::{Version, VersionReq}; // Pre-releases NOT matched by generic ranges let req = VersionReq::parse(">=1.0.0")?; let pre = Version::parse("1.0.0-alpha")?; assert!(!req.matches(&pre)); // But DO match explicit pre-release requirements let req_pre = VersionReq::parse(">=1.0.0-alpha")?; assert!(req_pre.matches(&pre)); ``` -------------------------------- ### Parsing Versions Source: https://github.com/dtolnay/semver/blob/master/_autodocs/INDEX.md Parse version strings into structured Version, VersionReq, and Comparator objects. Also shows how to create Prerelease and BuildMetadata objects. ```APIDOC ## Parsing ```rust Version::parse("1.2.3")? → Version VersionReq::parse("^1.0")? → VersionReq Comparator::parse(">=1.0.0")? → Comparator Prerelease::new("alpha.1")? → Prerelease BuildMetadata::new("build123")? → BuildMetadata ``` ``` -------------------------------- ### Parse and Match Semantic Versions Source: https://github.com/dtolnay/semver/blob/master/_autodocs/README.md Demonstrates basic parsing of a version string and a version requirement, and checks if the version matches the requirement. Requires the `semver` crate. ```rust use semver::{Version, VersionReq}; let version = Version::parse("1.2.3")?; let requirement = VersionReq::parse("^1.0")?; if requirement.matches(&version) { println!("✓ Version is compatible"); } ``` -------------------------------- ### Version Comparison with Build Metadata Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/version.md Demonstrates the difference between precedence comparison (ignoring build metadata) and total ordering (including build metadata). Use `cmp_precedence` for semantic versioning precedence and standard operators for exact equality. ```rust let v1 = Version::parse("1.0.0").unwrap(); let v2 = Version::parse("1.0.0+build1").unwrap(); let v3 = Version::parse("1.0.0+build2").unwrap(); assert_eq!(v1.cmp_precedence(&v2), Ordering::Equal); // Equal by precedence assert!(v1 < v2); // v1 is less than v2 in total order (no build vs build1) assert!(v2 < v3); // build1 < build2 ``` -------------------------------- ### Op::Exact Usage Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/comparator.md Demonstrates parsing and checking the Op::Exact comparator. Handles exact version matching with implicit expansion for partial versions. ```rust use semver::{Comparator, Op}; let cmp = Comparator::parse("=1.2.3").unwrap(); assert_eq!(cmp.op, Op::Exact); let cmp_partial = Comparator::parse("=1.2").unwrap(); // Equivalent to >=1.2.0, <1.3.0 ``` -------------------------------- ### Parse and Match Version Requirements Source: https://github.com/dtolnay/semver/blob/master/README.md Demonstrates parsing a version requirement string and checking if specific versions satisfy it. Ensure the `semver` crate is added to your Cargo.toml dependencies. ```rust use semver::{BuildMetadata, Prerelease, Version, VersionReq}; fn main() { let req = VersionReq::parse(">=1.2.3, <1.8.0").unwrap(); // Check whether this requirement matches version 1.2.3-alpha.1 (no) let version = Version { major: 1, minor: 2, patch: 3, pre: Prerelease::new("alpha.1").unwrap(), build: BuildMetadata::EMPTY, }; assert!(!req.matches(&version)); // Check whether it matches 1.3.0 (yes it does) let version = Version::parse("1.3.0").unwrap(); assert!(req.matches(&version)); } ``` -------------------------------- ### Check Semver Version Compatibility Source: https://github.com/dtolnay/semver/blob/master/_autodocs/REFERENCE.md Shows how to use VersionReq to check if a given version satisfies a version requirement. ```rust use semver::{Version, VersionReq}; let req = VersionReq::parse("^1.2")?; let version = Version::parse("1.5.3")?; if req.matches(&version) { println!("✓ Version is compatible"); } ``` -------------------------------- ### BuildMetadata::EMPTY Source: https://github.com/dtolnay/semver/blob/master/_autodocs/types.md An empty build metadata constant. ```APIDOC ## BuildMetadata::EMPTY ### Description An empty build metadata constant. ### Usage ```rust use semver::BuildMetadata; let metadata = BuildMetadata::EMPTY; ``` ``` -------------------------------- ### Parsing SemVer Components Source: https://github.com/dtolnay/semver/blob/master/_autodocs/INDEX.md Demonstrates parsing of individual SemVer components like Version, VersionReq, Comparator, Prerelease, and BuildMetadata. Requires successful parsing to avoid errors. ```rust Version::parse("1.2.3")? → Version VersionReq::parse("^1.0")? → VersionReq Comparator::parse(">=1.0.0")? → Comparator Prerelease::new("alpha.1")? → Prerelease BuildMetadata::new("build123")? → BuildMetadata ``` -------------------------------- ### Find Compatible Versions Source: https://github.com/dtolnay/semver/blob/master/_autodocs/REFERENCE.md Filters a list of candidate versions against a requirement and returns a sorted list of compatible versions. Requires importing `Version` and `VersionReq` from the `semver` crate. Versions are sorted by precedence. ```rust use semver::{Version, VersionReq}; fn find_compatible(requirement: &str, candidates: &[&str]) -> Result, Box> { let req = VersionReq::parse(requirement)?; let mut compatible = Vec::new(); for candidate in candidates { let version = Version::parse(candidate)?; if req.matches(&version) { compatible.push(version); } } compatible.sort_by(Version::cmp_precedence); Ok(compatible) } let versions = find_compatible("~1.2", &["1.2.0", "1.2.5", "1.3.0", "1.2.3-beta"])?; // Returns [1.2.0, 1.2.3-beta, 1.2.5] sorted by precedence ``` -------------------------------- ### Op::LessEq Usage Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/comparator.md Demonstrates parsing and matching with the Op::LessEq comparator. Use for less than or equal to version checks. ```rust use semver::{Version, Comparator}; let cmp = Comparator::parse("<=1.2.3").unwrap(); assert!(cmp.matches(&Version::parse("1.2.3").unwrap())); assert!(cmp.matches(&Version::parse("1.0.0").unwrap())); assert!(!cmp.matches(&Version::parse("1.2.4").unwrap())); ``` -------------------------------- ### Semver Exact Operator Matching Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Demonstrates how the exact operator (=) matches a specific version or expands to a range for partial version specifications. ```semver =1.2.3 → exact 1.2.3 =1.2 → >=1.2.0, <1.3.0 =1 → >=1.0.0, <2.0.0 ``` -------------------------------- ### Enable Serde Feature for Serialization Source: https://github.com/dtolnay/semver/blob/master/_autodocs/configuration.md Enable the `serde` feature to allow serialization and deserialization of semver types. This requires the `serde` crate as a dependency. ```toml [dependencies] semver = { version = "1.0", features = ["serde"] } serde = { version = "1.0", features = ["derive"] } ``` -------------------------------- ### BuildMetadata::new Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Creates a BuildMetadata instance by parsing a string. This method is used to convert a string representation of build metadata into a structured BuildMetadata object. ```APIDOC ## BuildMetadata::new Create `BuildMetadata` by parsing from a string representation. ```rust pub fn new(text: &str) -> Result ``` ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | &str | Yes | — | Build metadata string without the leading plus sign (e.g., "20130313144700" or "zstd.1.5.0") | ### Return Type Returns `Result`. On success, returns a parsed `BuildMetadata`. On failure, returns an `Error` describing the parsing failure. ### Syntax Build metadata identifiers are dot-separated components, each of which: - Contains only ASCII alphanumerics and hyphens: `0-9`, `A-Z`, `a-z`, `-` - Must not be empty (no consecutive dots) - Unlike version numbers, **leading zeros ARE allowed** ### Errors | Error Condition | Description | |-----------------|-------------| | Empty segment | Contains consecutive dots or ends with a dot | | Invalid characters | Contains characters outside the allowed set | **Note**: Leading zeros are permitted in build metadata, unlike in other parts of the version string. ### Example ```rust use semver::BuildMetadata; let build = BuildMetadata::new("20130313144700").unwrap(); assert_eq!(build.as_str(), "20130313144700"); let build = BuildMetadata::new("zstd.1.5.0").unwrap(); assert_eq!(build.as_str(), "zstd.1.5.0"); let build = BuildMetadata::new("001").unwrap(); // Leading zeros allowed assert_eq!(build.as_str(), "001"); // Invalid build metadata assert!(BuildMetadata::new("..").is_err()); // Empty segments assert!(BuildMetadata::new("zstd_1").is_err()); // Invalid character (underscore) ``` ``` -------------------------------- ### Pre-release Version Comparison Logic Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Compares two pre-release version identifiers lexicographically, handling numeric and non-numeric components, and tie-breaking by length. This logic is crucial for establishing the correct order of pre-release versions. ```rust match (self.is_empty(), rhs.is_empty()) { (true, true) → Equal (true, false) → Greater // release > pre-release (false, true) → Less // pre-release < release (false, false) → { // Lexicographic component comparison for (lhs_component, rhs_component) in split by '.' { if numeric(lhs) && numeric(rhs) { → compare as numbers (length-based for tie) } else if numeric(lhs) && !numeric(rhs) { → Less (numeric < non-numeric) } else if !numeric(lhs) && numeric(rhs) { → Greater (non-numeric > numeric) } else { → ASCII string comparison } // If not equal, return that result } // All common components equal if lhs has more → Greater if rhs has more → Less else → Equal } } ``` -------------------------------- ### Version Component Ordering Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Compares version components (major, minor, patch) lexicographically. Build metadata is included in the total order, differing from standard SemVer precedence rules. ```rust (major, minor, patch, &pre, &build) compared lexicographically → numeric tuple comparison by components → build metadata included in total order (unlike SemVer precedence) ``` -------------------------------- ### Performance Characteristics Table Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Presents a performance comparison table for operations on inline, heap, and empty identifier storage representations, detailing time complexity for creation, cloning, dropping, string conversion, comparison, and hashing. ```text Operation | Inline (1-8 bytes) | Heap (9+ bytes) | Empty ---------------------------|-------------------|-----------------|------- Creation | O(1) copy | O(n) allocate | O(1) Clone | O(1) copy | O(n) allocate | O(1) Drop | O(1) | O(1) deallocate | O(1) as_str() call | O(1) length comp | O(1) decode | O(1) Comparison | O(k) components | O(k) components | O(k) Hash computation | O(n) hash | O(n) hash | O(n) ``` -------------------------------- ### Op::Less Usage Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/comparator.md Demonstrates parsing and matching with the Op::Less comparator. Use for strictly less than version checks. ```rust use semver::{Version, Comparator}; let cmp = Comparator::parse("<2.0.0").unwrap(); assert!(cmp.matches(&Version::parse("1.9.9").unwrap())); assert!(!cmp.matches(&Version::parse("2.0.0").unwrap())); ``` -------------------------------- ### Parse and Handle Version Errors Source: https://github.com/dtolnay/semver/blob/master/_autodocs/README.md Shows how to parse a version string and handle potential errors using a match statement. This is a common pattern for validating version inputs. ```rust use semver::Version; match Version::parse("1.0.0") { Ok(v) => println!("{}", v), Err(e) => eprintln!("Invalid version: {}", e), } ``` -------------------------------- ### Prerelease::as_str Usage Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/prerelease.md Retrieves the pre-release identifier as a string slice. For Prerelease::EMPTY, it returns an empty string. ```rust use semver::Prerelease; let pre = Prerelease::new("beta").unwrap(); assert_eq!(pre.as_str(), "beta"); assert_eq!(Prerelease::EMPTY.as_str(), ""); ``` -------------------------------- ### Enable Serde Serialization/Deserialization Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md This code enables `serde` support, allowing `Version`, `VersionReq`, and `Comparator` types to be serialized and deserialized as strings. This is compiled only when the 'serde' feature is enabled. ```rust // src/serde.rs (only compiled with feature="serde") impl Serialize for Version { ... } impl<'de> Deserialize<'de> for Version { ... } // Similar for VersionReq and Comparator ``` -------------------------------- ### Wildcard Matching with Comparator Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/comparator.md Demonstrates how to use the wildcard operator (`*`) with the Comparator struct to match any version within a specified precision level. This is useful for flexible version comparisons. ```rust use semver::{Version, Comparator}; let cmp = Comparator::parse("1.2.*").unwrap(); // Matches any 1.2.x version assert!(cmp.matches(&Version::parse("1.2.0").unwrap())); assert!(cmp.matches(&Version::parse("1.2.99").unwrap())); assert!(!cmp.matches(&Version::parse("1.3.0").unwrap())); let cmp = Comparator::parse("1.*").unwrap(); // Matches any 1.x.x version assert!(cmp.matches(&Version::parse("1.0.0").unwrap())); assert!(cmp.matches(&Version::parse("1.99.99").unwrap())); assert!(!cmp.matches(&Version::parse("2.0.0").unwrap())); ``` -------------------------------- ### Prerelease::new Source: https://github.com/dtolnay/semver/blob/master/_autodocs/types.md Parses a string into a Prerelease identifier. Returns an error if the string is not a valid pre-release identifier according to SemVer syntax rules. ```APIDOC ## Prerelease::new ### Description Parses a string into a Prerelease identifier. ### Method `fn new(text: &str) -> Result` ### Parameters #### Path Parameters - **text** (str) - Required - The string to parse as a pre-release identifier. ### Response #### Success Response (Result) - **Self** - The parsed Prerelease identifier. #### Error Response (Result) - **Error** - An error if the input string is not a valid pre-release identifier. ### Request Example ```rust use semver::Prerelease; let prerelease = Prerelease::new("alpha.1"); ``` ``` -------------------------------- ### Prerelease::as_str Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/prerelease.md Retrieves the pre-release identifier as a string slice. ```APIDOC ## Prerelease::as_str ### Description Access the pre-release identifier as a string. ### Method ```rust pub fn as_str(&self) -> &str ``` ### Return Type Returns a `&str` containing the pre-release identifier. Returns an empty string for `Prerelease::EMPTY`. ### Example ```rust use semver::Prerelease; let pre = Prerelease::new("beta").unwrap(); assert_eq!(pre.as_str(), "beta"); assert_eq!(Prerelease::EMPTY.as_str(), ""); ``` ``` -------------------------------- ### Matching Versions Source: https://github.com/dtolnay/semver/blob/master/_autodocs/INDEX.md Check if a version matches a given requirement or comparator. ```APIDOC ## Matching ```rust req.matches(&version) → bool cmp.matches(&version) → bool ``` ``` -------------------------------- ### Version::cmp_precedence Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/version.md Compares two Version instances based on SemVer precedence rules, ignoring build metadata. ```APIDOC ## Version::cmp_precedence ### Description Compare the major, minor, patch, and pre-release values of two versions, disregarding build metadata. This implements the SemVer "precedence" comparison as defined in the specification. ### Signature ```rust pub fn cmp_precedence(&self, other: &Self) -> Ordering ``` ### Parameters #### Path Parameters - **other** (&Version) - Required - Version to compare against ### Return Type Returns `core::cmp::Ordering` indicating the relationship: - `Ordering::Less` if `self` is less than `other` - `Ordering::Equal` if versions are equal (ignoring build metadata) - `Ordering::Greater` if `self` is greater than `other` ### Behavior This method implements the exact comparison semantics of the SemVer specification: - Versions differing only in build metadata are considered equal - Pre-release versions are less than release versions with the same major.minor.patch - Pre-release identifiers are compared lexicographically by dot-separated components - Numeric-only identifiers are compared numerically; alphanumeric ones lexically - Numeric identifiers are always less than non-numeric identifiers ### Example ```rust use semver::Version; use std::cmp::Ordering; let v1 = Version::parse("1.0.0-alpha").unwrap(); let v2 = Version::parse("1.0.0").unwrap(); let v3 = Version::parse("1.0.0+build123").unwrap(); assert_eq!(v1.cmp_precedence(&v2), Ordering::Less); assert_eq!(v2.cmp_precedence(&v3), Ordering::Equal); // Build metadata ignored assert_eq!(v2.cmp_precedence(&v2), Ordering::Equal); // Sorting versions by precedence let mut versions = [ Version::parse("1.20.0+c144a98").unwrap(), Version::parse("1.0.0-alpha").unwrap(), Version::parse("1.0.0").unwrap(), ]; versions.sort_by(Version::cmp_precedence); assert_eq!(versions[0], Version::parse("1.0.0-alpha").unwrap()); ``` ``` -------------------------------- ### BuildMetadata::as_str Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Retrieves the build metadata as a string slice. This method is useful for displaying or comparing the build metadata. ```APIDOC ## BuildMetadata::as_str Access the build metadata as a string. ```rust pub fn as_str(&self) -> &str ``` ### Return Type Returns a `&str` containing the build metadata. Returns an empty string for `BuildMetadata::EMPTY`. ### Example ```rust use semver::BuildMetadata; let build = BuildMetadata::new("001").unwrap(); assert_eq!(build.as_str(), "001"); assert_eq!(BuildMetadata::EMPTY.as_str(), ""); ``` ``` -------------------------------- ### VersionReq::matches Method Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/versionreq.md Checks if a given Version satisfies the VersionReq. Pre-release versions have specific matching rules, only matching if the requirement explicitly includes a compatible pre-release comparator. ```rust use semver::{Version, VersionReq}; let req = VersionReq::parse(">=1.2.3, <1.8.0").unwrap(); // Release version matches assert!(req.matches(&Version::parse("1.3.0").unwrap())); assert!(req.matches(&Version::parse("1.2.3").unwrap())); assert!(!req.matches(&Version::parse("1.1.0").unwrap())); assert!(!req.matches(&Version::parse("2.0.0").unwrap())); // Pre-release version does NOT match the broad range assert!(!req.matches(&Version::parse("1.2.3-alpha.1").unwrap())); // But matches a specific pre-release in the requirement let req_pre = VersionReq::parse(">=1.2.3-alpha").unwrap(); assert!(req_pre.matches(&Version::parse("1.2.3-alpha.1").unwrap())); ``` -------------------------------- ### Version Source: https://github.com/dtolnay/semver/blob/master/_autodocs/types.md Represents a complete semantic version as specified by semver.org. It includes major, minor, and patch numbers, along with optional pre-release and build metadata. ```APIDOC ## Version ### Description A complete semantic version as specified by https://semver.org. Represents a version identifier with three numeric components (major, minor, patch) and optional pre-release and build metadata identifiers. ### Fields - **major** (u64) - Yes - Major version number (0-u64::MAX) - **minor** (u64) - Yes - Minor version number (0-u64::MAX) - **patch** (u64) - Yes - Patch version number (0-u64::MAX) - **pre** (Prerelease) - Yes - Pre-release identifier; use `Prerelease::EMPTY` for releases - **build** (BuildMetadata) - Yes - Build metadata identifier; use `BuildMetadata::EMPTY` if absent ### Used By - `VersionReq::matches(&self, version: &Version) -> bool` - `Comparator::matches(&self, version: &Version) -> bool` - Returned from `Version::parse(text: &str) -> Result` ### See Also - [Version API Reference](./api-reference/version.md) ``` -------------------------------- ### Ignore Build Metadata in Version Requirements and Precedence Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Demonstrates that build metadata is completely ignored when checking if a version matches a requirement or when comparing version precedence. Ensure `semver` and `VersionReq` are imported. ```rust use semver::{Version, VersionReq}; let req = VersionReq::parse("1.0").unwrap(); let v1 = Version::parse("1.0.0").unwrap(); let v2 = Version::parse("1.0.0+build123").unwrap(); let v3 = Version::parse("1.0.0+otherbuild").unwrap(); // All match the requirement equally assert!(req.matches(&v1)); assert!(req.matches(&v2)); assert!(req.matches(&v3)); // For precedence comparison, build is ignored assert_eq!(v1.cmp_precedence(&v2), std::cmp::Ordering::Equal); assert_eq!(v2.cmp_precedence(&v3), std::cmp::Ordering::Equal); ``` -------------------------------- ### Use Build Metadata for External Library Version Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/buildmetadata.md Indicates the external library version a Rust wrapper was compiled against. Ensure `semver` crate is imported. ```rust use semver::Version; // libgit2-sys is built against libgit2 1.1.0 let version = Version::parse("0.12.20+1.1.0").unwrap(); assert_eq!(version.build.as_str(), "1.1.0"); ``` -------------------------------- ### Op::Tilde Usage Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/comparator.md Demonstrates parsing and matching with the Op::Tilde comparator. Allows patch updates but fixes major and minor versions. ```rust use semver::{Version, Comparator}; let cmp = Comparator::parse("~1.2.3").unwrap(); // Allows 1.2.3, 1.2.4, 1.2.5, but not 1.3.0 or 2.0.0 assert!(cmp.matches(&Version::parse("1.2.5").unwrap())); assert!(!cmp.matches(&Version::parse("1.3.0").unwrap())); let cmp_partial = Comparator::parse("~1.2").unwrap(); // Only matches exactly 1.2 assert!(cmp_partial.matches(&Version::parse("1.2.0").unwrap())); assert!(!cmp_partial.matches(&Version::parse("1.2.1").unwrap())); ``` -------------------------------- ### Version Structure Definition Source: https://github.com/dtolnay/semver/blob/master/_autodocs/REFERENCE.md Defines the components of a semantic version, including major, minor, patch, prerelease, and build metadata. Prerelease and build metadata are optional. ```rust Version { major: u64, // Required minor: u64, // Required patch: u64, // Required pre: Prerelease, // Optional (use EMPTY for release) build: BuildMetadata, // Optional (use EMPTY if absent) } ``` -------------------------------- ### Op::Exact (`=`) Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/comparator.md Exact version matching with implicit expansion for partial versions. It can match a full version, a major.minor version, or a major version. ```APIDOC ## = ### Description Exact version matching with implicit expansion for partial versions. ### Syntax - `=I.J.K` — exactly version I.J.K - `=I.J` — equivalent to `>=I.J.0, =I.0.0, <(I+1).0.0` ### Example ```rust use semver::{Comparator, Op}; let cmp = Comparator::parse("=1.2.3").unwrap(); assert_eq!(cmp.op, Op::Exact); let cmp_partial = Comparator::parse("=1.2").unwrap(); // Equivalent to >=1.2.0, <1.3.0 ``` ``` -------------------------------- ### Op::GreaterEq Usage Source: https://github.com/dtolnay/semver/blob/master/_autodocs/api-reference/comparator.md Demonstrates parsing and matching with the Op::GreaterEq comparator. Use for greater than or equal to version checks. ```rust use semver::{Version, Comparator}; let cmp = Comparator::parse(">=1.2.3").unwrap(); assert!(cmp.matches(&Version::parse("1.2.3").unwrap())); assert!(cmp.matches(&Version::parse("2.0.0").unwrap())); assert!(!cmp.matches(&Version::parse("1.2.2").unwrap())); ``` -------------------------------- ### Semver Wildcard Operator Matching Source: https://github.com/dtolnay/semver/blob/master/_autodocs/architecture.md Shows how the wildcard (*) operator matches any version at a specified precision, useful for broad compatibility within a major or minor version. ```semver 1.2.* → >=1.2.0, <1.3.0 (same major.minor) 1.* → >=1.0.0, <2.0.0 (same major) ```