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:
Jiahao XU 2022-12-01 18:05:00 +11:00 committed by GitHub
parent ab3e47c42b
commit 8a5577297e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 40 deletions

View file

@ -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,14 +33,12 @@ 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) crate_name: name.into(),
.await err,
.map_err(|err| BinstallError::CratesIoApi { })
crate_name: name.into(), })?;
err: Box::new(err),
})?;
// Locate matching version // Locate matching version
let version_iter = base_info.versions.iter().filter(|v| !v.yanked); let version_iter = base_info.versions.iter().filter(|v| !v.yanked);

View file

@ -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))
}
}

View file

@ -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,
}) })
} }

View file

@ -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())
} }
}; };