mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-21 13:08:42 +00:00
Optimize BinstallError
: Reduce size from 40B to 32B (#581)
* Optimize `BinstallError::CratesIoApi`: Extract new type `errors::CratesIoApiError` and box it Also improve `<CratesIoApiError as Display>::fmt` impl. * Optimize `BinstallError::SubProcess`: Use `Box<str>` instead of `String` * Optimize `BinstallError::CargoManifest`: Box `CargoTomlError` * Optimize `BinstallError::VersionParse`: Extract `VersionParseError` and box it Also improve `<VersionParseError as Display>::fmt` impl. * Optimize `BinstallError::CrateContext`: Extract `CrateContextError` and box it in * Optimize `install_from_source`: Only format `cmd` on err Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
ab3e47c42b
commit
8a5577297e
4 changed files with 58 additions and 40 deletions
|
@ -6,7 +6,7 @@ use semver::VersionReq;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::BinstallError,
|
errors::{BinstallError, CratesIoApiError},
|
||||||
helpers::{
|
helpers::{
|
||||||
download::Download,
|
download::Download,
|
||||||
remote::{Client, Url},
|
remote::{Client, Url},
|
||||||
|
@ -33,13 +33,11 @@ pub async fn fetch_crate_cratesio(
|
||||||
debug!("Looking up crate information");
|
debug!("Looking up crate information");
|
||||||
|
|
||||||
// Fetch online crate information
|
// Fetch online crate information
|
||||||
let base_info =
|
let base_info = crates_io_api_client.get_crate(name).await.map_err(|err| {
|
||||||
crates_io_api_client
|
Box::new(CratesIoApiError {
|
||||||
.get_crate(name)
|
|
||||||
.await
|
|
||||||
.map_err(|err| BinstallError::CratesIoApi {
|
|
||||||
crate_name: name.into(),
|
crate_name: name.into(),
|
||||||
err: Box::new(err),
|
err,
|
||||||
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Locate matching version
|
// Locate matching version
|
||||||
|
|
|
@ -8,14 +8,38 @@ use binstalk_downloader::{
|
||||||
download::{DownloadError, ZipError},
|
download::{DownloadError, ZipError},
|
||||||
remote::{Error as RemoteError, HttpError, ReqwestError},
|
remote::{Error as RemoteError, HttpError, ReqwestError},
|
||||||
};
|
};
|
||||||
|
use cargo_toml::Error as CargoTomlError;
|
||||||
use compact_str::CompactString;
|
use compact_str::CompactString;
|
||||||
use crates_io_api::Error as CratesIoApiError;
|
|
||||||
use miette::{Diagnostic, Report};
|
use miette::{Diagnostic, Report};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tinytemplate::error::Error as TinyTemplateError;
|
use tinytemplate::error::Error as TinyTemplateError;
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
use tracing::{error, warn};
|
use tracing::{error, warn};
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
#[error("crates.io API error for {crate_name}: {err}")]
|
||||||
|
pub struct CratesIoApiError {
|
||||||
|
pub crate_name: CompactString,
|
||||||
|
#[source]
|
||||||
|
pub err: crates_io_api::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
#[error("version string '{v}' is not semver: {err}")]
|
||||||
|
pub struct VersionParseError {
|
||||||
|
pub v: CompactString,
|
||||||
|
#[source]
|
||||||
|
pub err: semver::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
#[error("For crate {crate_name}: {err}")]
|
||||||
|
pub struct CrateContextError {
|
||||||
|
crate_name: CompactString,
|
||||||
|
#[source]
|
||||||
|
err: BinstallError,
|
||||||
|
}
|
||||||
|
|
||||||
/// Error kinds emitted by cargo-binstall.
|
/// Error kinds emitted by cargo-binstall.
|
||||||
#[derive(Error, Diagnostic, Debug)]
|
#[derive(Error, Diagnostic, Debug)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
@ -93,7 +117,10 @@ pub enum BinstallError {
|
||||||
/// - Exit: 70
|
/// - Exit: 70
|
||||||
#[error("subprocess {command} errored with {status}")]
|
#[error("subprocess {command} errored with {status}")]
|
||||||
#[diagnostic(severity(error), code(binstall::subprocess))]
|
#[diagnostic(severity(error), code(binstall::subprocess))]
|
||||||
SubProcess { command: String, status: ExitStatus },
|
SubProcess {
|
||||||
|
command: Box<str>,
|
||||||
|
status: ExitStatus,
|
||||||
|
},
|
||||||
|
|
||||||
/// A generic I/O error.
|
/// A generic I/O error.
|
||||||
///
|
///
|
||||||
|
@ -109,17 +136,13 @@ pub enum BinstallError {
|
||||||
///
|
///
|
||||||
/// - Code: `binstall::crates_io_api`
|
/// - Code: `binstall::crates_io_api`
|
||||||
/// - Exit: 76
|
/// - Exit: 76
|
||||||
#[error("crates.io API error")]
|
#[error(transparent)]
|
||||||
#[diagnostic(
|
#[diagnostic(
|
||||||
severity(error),
|
severity(error),
|
||||||
code(binstall::crates_io_api),
|
code(binstall::crates_io_api),
|
||||||
help("Check that the crate name you provided is correct.\nYou can also search for a matching crate at: https://lib.rs/search?q={crate_name}")
|
help("Check that the crate name you provided is correct.\nYou can also search for a matching crate at: https://lib.rs/search?q={}", .0.crate_name)
|
||||||
)]
|
)]
|
||||||
CratesIoApi {
|
CratesIoApi(#[from] Box<CratesIoApiError>),
|
||||||
crate_name: CompactString,
|
|
||||||
#[source]
|
|
||||||
err: Box<CratesIoApiError>,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// The override path to the cargo manifest is invalid or cannot be resolved.
|
/// The override path to the cargo manifest is invalid or cannot be resolved.
|
||||||
///
|
///
|
||||||
|
@ -143,7 +166,7 @@ pub enum BinstallError {
|
||||||
code(binstall::cargo_manifest),
|
code(binstall::cargo_manifest),
|
||||||
help("If you used --manifest-path, check the Cargo.toml syntax.")
|
help("If you used --manifest-path, check the Cargo.toml syntax.")
|
||||||
)]
|
)]
|
||||||
CargoManifest(#[from] cargo_toml::Error),
|
CargoManifest(Box<CargoTomlError>),
|
||||||
|
|
||||||
/// A version is not valid semver.
|
/// A version is not valid semver.
|
||||||
///
|
///
|
||||||
|
@ -152,13 +175,9 @@ pub enum BinstallError {
|
||||||
///
|
///
|
||||||
/// - Code: `binstall::version::parse`
|
/// - Code: `binstall::version::parse`
|
||||||
/// - Exit: 80
|
/// - Exit: 80
|
||||||
#[error("version string '{v}' is not semver")]
|
#[error(transparent)]
|
||||||
#[diagnostic(severity(error), code(binstall::version::parse))]
|
#[diagnostic(severity(error), code(binstall::version::parse))]
|
||||||
VersionParse {
|
VersionParse(#[from] Box<VersionParseError>),
|
||||||
v: CompactString,
|
|
||||||
#[source]
|
|
||||||
err: semver::Error,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// No available version matches the requirements.
|
/// No available version matches the requirements.
|
||||||
///
|
///
|
||||||
|
@ -302,12 +321,8 @@ pub enum BinstallError {
|
||||||
NoFallbackToCargoInstall,
|
NoFallbackToCargoInstall,
|
||||||
|
|
||||||
/// A wrapped error providing the context of which crate the error is about.
|
/// A wrapped error providing the context of which crate the error is about.
|
||||||
#[error("For crate {crate_name}: {error}")]
|
#[error(transparent)]
|
||||||
CrateContext {
|
CrateContext(Box<CrateContextError>),
|
||||||
#[source]
|
|
||||||
error: Box<BinstallError>,
|
|
||||||
crate_name: CompactString,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinstallError {
|
impl BinstallError {
|
||||||
|
@ -339,7 +354,7 @@ impl BinstallError {
|
||||||
EmptySourceFilePath => 92,
|
EmptySourceFilePath => 92,
|
||||||
InvalidStrategies(..) => 93,
|
InvalidStrategies(..) => 93,
|
||||||
NoFallbackToCargoInstall => 94,
|
NoFallbackToCargoInstall => 94,
|
||||||
CrateContext { error, .. } => error.exit_number(),
|
CrateContext(context) => context.err.exit_number(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// reserved codes
|
// reserved codes
|
||||||
|
@ -361,10 +376,10 @@ impl BinstallError {
|
||||||
|
|
||||||
/// Add crate context to the error
|
/// Add crate context to the error
|
||||||
pub fn crate_context(self, crate_name: impl Into<CompactString>) -> Self {
|
pub fn crate_context(self, crate_name: impl Into<CompactString>) -> Self {
|
||||||
Self::CrateContext {
|
Self::CrateContext(Box::new(CrateContextError {
|
||||||
error: Box::new(self),
|
err: self,
|
||||||
crate_name: crate_name.into(),
|
crate_name: crate_name.into(),
|
||||||
}
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,3 +453,9 @@ impl From<TinyTemplateError> for BinstallError {
|
||||||
BinstallError::Template(Box::new(e))
|
BinstallError::Template(Box::new(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<CargoTomlError> for BinstallError {
|
||||||
|
fn from(e: CargoTomlError) -> Self {
|
||||||
|
BinstallError::CargoManifest(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -131,8 +131,6 @@ async fn install_from_source(
|
||||||
cmd.arg("--force");
|
cmd.arg("--force");
|
||||||
}
|
}
|
||||||
|
|
||||||
let command_string = format!("{cmd:?}");
|
|
||||||
|
|
||||||
let mut child = jobserver_client.configure_and_run(&mut cmd, |cmd| cmd.spawn())?;
|
let mut child = jobserver_client.configure_and_run(&mut cmd, |cmd| cmd.spawn())?;
|
||||||
|
|
||||||
debug!("Spawned command pid={:?}", child.id());
|
debug!("Spawned command pid={:?}", child.id());
|
||||||
|
@ -144,7 +142,7 @@ async fn install_from_source(
|
||||||
} else {
|
} else {
|
||||||
error!("Cargo errored! {status:?}");
|
error!("Cargo errored! {status:?}");
|
||||||
Err(BinstallError::SubProcess {
|
Err(BinstallError::SubProcess {
|
||||||
command: command_string,
|
command: format!("{cmd:?}").into_boxed_str(),
|
||||||
status,
|
status,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use super::Options;
|
||||||
use crate::{
|
use crate::{
|
||||||
bins,
|
bins,
|
||||||
drivers::fetch_crate_cratesio,
|
drivers::fetch_crate_cratesio,
|
||||||
errors::BinstallError,
|
errors::{BinstallError, VersionParseError},
|
||||||
fetchers::{Data, Fetcher, TargetData},
|
fetchers::{Data, Fetcher, TargetData},
|
||||||
helpers::remote::Client,
|
helpers::remote::Client,
|
||||||
manifests::cargo_toml_binstall::{Meta, PkgMeta, PkgOverride},
|
manifests::cargo_toml_binstall::{Meta, PkgMeta, PkgOverride},
|
||||||
|
@ -409,10 +409,11 @@ impl PackageInfo {
|
||||||
let new_version = match Version::parse(&new_version_str) {
|
let new_version = match Version::parse(&new_version_str) {
|
||||||
Ok(new_version) => new_version,
|
Ok(new_version) => new_version,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(BinstallError::VersionParse {
|
return Err(Box::new(VersionParseError {
|
||||||
v: new_version_str,
|
v: new_version_str,
|
||||||
err,
|
err,
|
||||||
})
|
})
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue