mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-28 08:10:02 +00:00
Optimize and generalize find_version
- Rm the process of collecting into `BTreeMap` in `find_version`. - Accept any type that implements trait `Version` Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
b2d09e2b13
commit
e308b275d5
2 changed files with 38 additions and 44 deletions
|
@ -34,22 +34,8 @@ pub async fn fetch_crate_cratesio(
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Locate matching version
|
// Locate matching version
|
||||||
let version_iter =
|
let version_iter = base_info.versions.iter().filter(|v| !v.yanked);
|
||||||
base_info
|
let (version, version_name) = find_version(version_req, version_iter)?;
|
||||||
.versions
|
|
||||||
.iter()
|
|
||||||
.filter_map(|v| if !v.yanked { Some(&v.num) } else { None });
|
|
||||||
let version_name = find_version(version_req, version_iter)?;
|
|
||||||
|
|
||||||
// Fetch information for the filtered version
|
|
||||||
let version = base_info
|
|
||||||
.versions
|
|
||||||
.iter()
|
|
||||||
.find(|v| v.num == version_name.to_string())
|
|
||||||
.ok_or_else(|| BinstallError::VersionUnavailable {
|
|
||||||
crate_name: name.into(),
|
|
||||||
v: version_name.clone(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
debug!("Found information for crate version: '{}'", version.num);
|
debug!("Found information for crate version: '{}'", version.num);
|
||||||
|
|
||||||
|
|
|
@ -1,48 +1,56 @@
|
||||||
use std::collections::BTreeSet;
|
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use semver::{Version, VersionReq};
|
use semver::VersionReq;
|
||||||
|
|
||||||
use crate::BinstallError;
|
use crate::BinstallError;
|
||||||
|
|
||||||
pub(super) fn find_version<'a, V: Iterator<Item = &'a String>>(
|
pub(super) trait Version {
|
||||||
|
/// Return `None` on error.
|
||||||
|
fn get_version(&self) -> Option<semver::Version>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Version> Version for &T {
|
||||||
|
fn get_version(&self) -> Option<semver::Version> {
|
||||||
|
(*self).get_version()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Version for crates_io_api::Version {
|
||||||
|
fn get_version(&self) -> Option<semver::Version> {
|
||||||
|
// Remove leading `v` for git tags
|
||||||
|
let ver_str = match self.num.strip_prefix('s') {
|
||||||
|
Some(v) => v,
|
||||||
|
None => &self.num,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse out version
|
||||||
|
semver::Version::parse(ver_str).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn find_version<Item: Version, VersionIter: Iterator<Item = Item>>(
|
||||||
requirement: &str,
|
requirement: &str,
|
||||||
version_iter: V,
|
version_iter: VersionIter,
|
||||||
) -> Result<Version, BinstallError> {
|
) -> Result<(Item, semver::Version), BinstallError> {
|
||||||
// Parse version requirement
|
// Parse version requirement
|
||||||
let version_req = VersionReq::parse(requirement).map_err(|err| BinstallError::VersionReq {
|
let version_req = VersionReq::parse(requirement).map_err(|err| BinstallError::VersionReq {
|
||||||
req: requirement.into(),
|
req: requirement.into(),
|
||||||
err,
|
err,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Filter for matching versions
|
version_iter
|
||||||
let filtered: BTreeSet<_> = version_iter
|
// Filter for matching versions
|
||||||
.filter_map(|v| {
|
.filter_map(|item| {
|
||||||
// Remove leading `v` for git tags
|
let ver = item.get_version()?;
|
||||||
let ver_str = match v.strip_prefix('s') {
|
|
||||||
Some(v) => v,
|
|
||||||
None => v,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse out version
|
|
||||||
let ver = Version::parse(ver_str).ok()?;
|
|
||||||
debug!("Version: {:?}", ver);
|
|
||||||
|
|
||||||
// Filter by version match
|
// Filter by version match
|
||||||
if version_req.matches(&ver) {
|
if version_req.matches(&ver) {
|
||||||
Some(ver)
|
debug!("Version: {:?}", ver);
|
||||||
|
Some((item, ver))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
// Return highest version
|
||||||
|
.max_by_key(|(_item, ver)| ver.clone())
|
||||||
debug!("Filtered: {:?}", filtered);
|
|
||||||
|
|
||||||
// Return highest version
|
|
||||||
filtered
|
|
||||||
.iter()
|
|
||||||
.max()
|
|
||||||
.cloned()
|
|
||||||
.ok_or(BinstallError::VersionMismatch { req: version_req })
|
.ok_or(BinstallError::VersionMismatch { req: version_req })
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue