Semver Requirement Matching
Parse semantic versions and requirement ranges, test whether a release satisfies a range, and pick the highest matching version.
Code
use semver::{Version, VersionReq};
fn matches(version: &str, requirement: &str) -> Result<bool, semver::Error> {
let parsed = Version::parse(version)?;
let requirement = VersionReq::parse(requirement)?;
Ok(requirement.matches(&parsed))
}
fn best_match(versions: &[&str], requirement: &str) -> Result<Option<Version>, semver::Error> {
let requirement = VersionReq::parse(requirement)?;
let mut best: Option<Version> = None;
for raw in versions {
let version = Version::parse(raw)?;
if !requirement.matches(&version) {
continue;
}
if best.as_ref().map_or(true, |current| version > *current) {
best = Some(version);
}
}
Ok(best)
}
fn main() {
let versions = ["1.2.0", "1.4.3", "2.0.0", "2.1.0-rc.1"];
println!("1.9.0 in ^1.2: {:?}", matches("1.9.0", "^1.2"));
println!("2.0.0 in ^1.2: {:?}", matches("2.0.0", "^1.2"));
println!("rc.1 in ^2.1: {:?}", matches("2.1.0-rc.1", "^2.1"));
println!("best in ~1.2: {:?}", best_match(&versions, "~1.2"));
println!("invalid range: {}", matches("1.0.0", "not-a-version").is_err());
}Report a problem with this exampleOpens a pre-filled issue on GitHub.