cargo-binstall/crates/lib/src/drivers/crates_io.rs
2022-09-04 22:47:18 +12:00

58 lines
1.6 KiB
Rust

use std::path::PathBuf;
use cargo_toml::Manifest;
use crates_io_api::AsyncClient;
use log::debug;
use reqwest::Client;
use semver::VersionReq;
use url::Url;
use crate::{
errors::BinstallError,
helpers::download::Download,
manifests::cargo_toml_binstall::{Meta, TarBasedFmt},
};
use super::find_version;
mod vfs;
mod visitor;
use visitor::ManifestVisitor;
/// Fetch a crate Cargo.toml by name and version from crates.io
pub async fn fetch_crate_cratesio(
client: &Client,
crates_io_api_client: &AsyncClient,
name: &str,
version_req: &VersionReq,
) -> Result<Manifest<Meta>, BinstallError> {
// Fetch / update index
debug!("Looking up crate information");
// Fetch online crate information
let base_info = crates_io_api_client
.get_crate(name.as_ref())
.await
.map_err(|err| BinstallError::CratesIoApi {
crate_name: name.into(),
err,
})?;
// Locate matching version
let version_iter = base_info.versions.iter().filter(|v| !v.yanked);
let (version, version_name) = find_version(version_req, version_iter)?;
debug!("Found information for crate version: '{}'", version.num);
// Download crate to temporary dir (crates.io or git?)
let crate_url = format!("https://crates.io/{}", version.dl_path);
debug!("Fetching crate from: {crate_url} and extracting Cargo.toml from it");
let manifest_dir_path: PathBuf = format!("{name}-{version_name}").into();
Download::new(client, Url::parse(&crate_url)?)
.and_visit_tar(TarBasedFmt::Tgz, ManifestVisitor::new(manifest_dir_path))
.await
}