Versioning
Parse a complex version string.
Constructs a semver::Version
from a complex version string using Version::parse
. The string
contains pre-release and build metadata as defined in the Semantic Versioning Specification.
Note that, in accordance with the Specification, build metadata is parsed and considered when comparing versions. In other words, two versions are not equal even if their build strings differ.
use std::error::Error; use semver::{BuildMetadata, Prerelease, Version}; fn main() -> Result<(), Box<dyn Error>> { let version_str = "1.0.49-125+g72ee7853"; let parsed_version = Version::parse(version_str)?; assert_ne!( parsed_version, Version { major: 1, minor: 0, patch: 49, pre: Prerelease::new("125").unwrap(), build: BuildMetadata::new("7208347").unwrap(), } ); assert_eq!( parsed_version.build, BuildMetadata::new("g72ee7853").unwrap(), ); let serialized_version = parsed_version.to_string(); assert_eq!(&serialized_version, version_str); Ok(()) }
Check if given version is pre-release.
Given two versions, the Prerelease
field will be EMPTY
if there is
not an optional pre-release identifier in the version string.
use std::error::Error; use semver::{Version, Prerelease}; fn main() -> Result<(), Box<dyn Error>> { let version_1 = Version::parse("1.0.0-alpha")?; let version_2 = Version::parse("1.0.0")?; assert_ne!(version_1.pre, Prerelease::EMPTY); assert_eq!(version_2.pre, Prerelease::EMPTY); Ok(()) }
Find the latest version satisfying given range
Given a list of version &strs, finds the latest semver::Version
.
semver::VersionReq
filters the list with VersionReq::matches
.
Also demonstrates semver
pre-release preferences.
use std::error::Error; use semver::{VersionReq, Version}; fn find_max_matching_version<'a, I>(version_req_str: &str, iterable: I) -> Result<Option<Version>, Box<dyn Error>> where I: IntoIterator<Item = &'a str>, { let vreq = VersionReq::parse(version_req_str)?; Ok( iterable .into_iter() .filter_map(|s| Version::parse(s).ok()) .filter(|s| vreq.matches(s)) .max(), ) } fn main() -> Result<(), Box<dyn Error>> { assert_eq!( find_max_matching_version("<= 1.0.0", vec!["0.9.0", "1.0.0", "1.0.1"])?, Some(Version::parse("1.0.0")?) ); assert_eq!( find_max_matching_version( ">1.2.3-alpha.3", vec![ "1.2.3-alpha.3", "1.2.3-alpha.4", "1.2.3-alpha.10", "1.2.3-beta.4", "3.4.5-alpha.9", ] )?, Some(Version::parse("1.2.3-beta.4")?) ); Ok(()) }
Check external command version for compatibility
Runs git --version
using Command
, then parses the version number into a
semver::Version
using Version::parse
. VersionReq::matches
compares
semver::VersionReq
to the parsed version. The command output resembles
"git version x.y.z".
use anyhow::{anyhow, Result}; use std::process::Command; use semver::{Version, VersionReq}; fn main() -> Result<()> { let version_constraint = "> 1.12.0"; let version_test = VersionReq::parse(version_constraint)?; let output = Command::new("git").arg("--version").output()?; if !output.status.success() { return Err(anyhow!("Command executed with failing error code")); } let stdout = String::from_utf8(output.stdout)?; let version = stdout.split(" ").last().ok_or_else(|| { anyhow!("Invalid command output") })?.trim_end(); let parsed_version = Version::parse(version)?; if !version_test.matches(&parsed_version) { return Err(anyhow!("Command version lower than minimum supported version (found {}, need {})", parsed_version, version_constraint)); } else { println!("git version constraint '{version_constraint}' satisfied for: {version}"); } Ok(()) }