Versioning
Parse and increment a version string.
Constructs a semver::Version
from a string literal using Version::parse
,
then increments it by patch, minor, and major version number one by one.
Note that in accordance with the Semantic Versioning Specification, incrementing the minor version number resets the patch version number to 0 and incrementing the major version number resets both the minor and patch version numbers to 0.
use semver::{Version, SemVerError}; fn main() -> Result<(), SemVerError> { let mut parsed_version = Version::parse("0.2.6")?; assert_eq!( parsed_version, Version { major: 0, minor: 2, patch: 6, pre: vec![], build: vec![], } ); parsed_version.increment_patch(); assert_eq!(parsed_version.to_string(), "0.2.7"); println!("New patch release: v{}", parsed_version); parsed_version.increment_minor(); assert_eq!(parsed_version.to_string(), "0.3.0"); println!("New minor release: v{}", parsed_version); parsed_version.increment_major(); assert_eq!(parsed_version.to_string(), "1.0.0"); println!("New major release: v{}", parsed_version); Ok(()) }
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 but not considered when comparing versions. In other words, two versions may be equal even if their build strings differ.
use semver::{Identifier, Version, SemVerError}; fn main() -> Result<(), SemVerError> { let version_str = "1.0.49-125+g72ee7853"; let parsed_version = Version::parse(version_str)?; assert_eq!( parsed_version, Version { major: 1, minor: 0, patch: 49, pre: vec![Identifier::Numeric(125)], build: vec![], } ); assert_eq!( parsed_version.build, vec![Identifier::AlphaNumeric(String::from("g72ee7853"))] ); let serialized_version = parsed_version.to_string(); assert_eq!(&serialized_version, version_str); Ok(()) }
Check if given version is pre-release.
Given two versions, is_prerelease
asserts that one is pre-release and the other is not.
use semver::{Version, SemVerError}; fn main() -> Result<(), SemVerError> { let version_1 = Version::parse("1.0.0-alpha")?; let version_2 = Version::parse("1.0.0")?; assert!(version_1.is_prerelease()); assert!(!version_2.is_prerelease()); 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 error_chain::error_chain; use semver::{Version, VersionReq}; error_chain! { foreign_links { SemVer(semver::SemVerError); SemVerReq(semver::ReqParseError); } } fn find_max_matching_version<'a, I>(version_req_str: &str, iterable: I) -> Result<Option<Version>> 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<()> { 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 error_chain::error_chain; use std::process::Command; use semver::{Version, VersionReq}; error_chain! { foreign_links { Io(std::io::Error); Utf8(std::string::FromUtf8Error); SemVer(semver::SemVerError); SemVerReq(semver::ReqParseError); } } 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() { error_chain::bail!("Command executed with failing error code"); } let stdout = String::from_utf8(output.stdout)?; let version = stdout.split(" ").last().ok_or_else(|| { "Invalid command output" })?; let parsed_version = Version::parse(version)?; if !version_test.matches(&parsed_version) { error_chain::bail!("Command version lower than minimum supported version (found {}, need {})", parsed_version, version_constraint); } Ok(()) }