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(()) }