mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-24 14:28:42 +00:00
Replace dep crates_io_api
with in-house solution (#846)
It also uses `max_stable_version` in the json downloaded from https://crates.io/api/v1/crates/$name if possible, which is equivalent to the version shown on https://crates.io/crates/$name . - Add new feat `json` to `binstalk-downloader` - Impl new async fn `Response::json` - use `Response::json` in `GhApiClient` impl - Mark all err types in binstalk-downloader as `non_exhaustive` - Ret `remote::Error` in `remote::Certificate::{from_pem, from_der}` instead of `ReqwestError`. - Refactor `BinstallError`: Merge variant `Unzip`, `Reqwest` & `Http` into one variant `Download`. - Manually download and parse json from httos://crates.io/api/v1 - Remove unused deps `crates_io_api` Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
c00d648dac
commit
8eee318ccd
17 changed files with 120 additions and 244 deletions
|
@ -74,7 +74,8 @@ zstd-thin = ["zstd/thin"]
|
|||
|
||||
cross-lang-fat-lto = ["zstd/fat-lto"]
|
||||
|
||||
gh-api-client = ["serde", "serde_json"]
|
||||
gh-api-client = ["json"]
|
||||
json = ["serde", "serde_json"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
|
@ -23,6 +23,7 @@ mod zip_extraction;
|
|||
pub use zip_extraction::ZipError;
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
#[non_exhaustive]
|
||||
pub enum DownloadError {
|
||||
#[error("Failed to extract zipfile: {0}")]
|
||||
Unzip(#[from] ZipError),
|
||||
|
|
|
@ -11,7 +11,7 @@ use tokio::sync::OnceCell;
|
|||
use crate::remote;
|
||||
|
||||
mod request;
|
||||
pub use request::{GhApiError, JsonError};
|
||||
pub use request::GhApiError;
|
||||
|
||||
/// default retry duration if x-ratelimit-reset is not found in response header
|
||||
const DEFAULT_RETRY_DURATION: Duration = Duration::from_secs(3);
|
||||
|
|
|
@ -8,22 +8,17 @@ use std::{
|
|||
|
||||
use compact_str::CompactString;
|
||||
use serde::Deserialize;
|
||||
use serde_json::from_slice as json_from_slice;
|
||||
use thiserror::Error as ThisError;
|
||||
use url::Url;
|
||||
|
||||
pub use serde_json::Error as JsonError;
|
||||
|
||||
use super::{remote, GhRelease};
|
||||
|
||||
#[derive(ThisError, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum GhApiError {
|
||||
#[error("IO Error: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
|
||||
#[error("Failed to parse json: {0}")]
|
||||
Json(#[from] JsonError),
|
||||
|
||||
#[error("Remote Error: {0}")]
|
||||
Remote(#[from] remote::Error),
|
||||
|
||||
|
@ -129,7 +124,5 @@ pub(super) async fn fetch_release_artifacts(
|
|||
return Ok(FetchReleaseRet::ReleaseNotFound);
|
||||
}
|
||||
|
||||
let bytes = response.error_for_status()?.bytes().await?;
|
||||
|
||||
Ok(FetchReleaseRet::Artifacts(json_from_slice(&bytes)?))
|
||||
Ok(FetchReleaseRet::Artifacts(response.json().await?))
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ pub use certificate::Certificate;
|
|||
mod request_builder;
|
||||
pub use request_builder::{RequestBuilder, Response};
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
pub use request_builder::JsonError;
|
||||
|
||||
const MAX_RETRY_DURATION: Duration = Duration::from_secs(120);
|
||||
const MAX_RETRY_COUNT: u8 = 3;
|
||||
const DEFAULT_RETRY_DURATION_FOR_RATE_LIMIT: Duration = Duration::from_millis(200);
|
||||
|
@ -35,12 +38,17 @@ const RETRY_DURATION_FOR_TIMEOUT: Duration = Duration::from_millis(200);
|
|||
const DEFAULT_MIN_TLS: tls::Version = tls::Version::TLS_1_2;
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
#[non_exhaustive]
|
||||
pub enum Error {
|
||||
#[error("Reqwest error: {0}")]
|
||||
Reqwest(#[from] reqwest::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Http(Box<HttpError>),
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
#[error("Failed to parse http response body as Json: {0}")]
|
||||
Json(#[from] JsonError),
|
||||
}
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
use reqwest::tls;
|
||||
|
||||
use super::ReqwestError;
|
||||
use super::Error;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Certificate(pub(super) tls::Certificate);
|
||||
|
||||
impl Certificate {
|
||||
/// Create a Certificate from a binary DER encoded certificate
|
||||
pub fn from_der(der: impl AsRef<[u8]>) -> Result<Self, ReqwestError> {
|
||||
tls::Certificate::from_der(der.as_ref()).map(Self)
|
||||
pub fn from_der(der: impl AsRef<[u8]>) -> Result<Self, Error> {
|
||||
tls::Certificate::from_der(der.as_ref())
|
||||
.map(Self)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
/// Create a Certificate from a PEM encoded certificate
|
||||
pub fn from_pem(pem: impl AsRef<[u8]>) -> Result<Self, ReqwestError> {
|
||||
tls::Certificate::from_pem(pem.as_ref()).map(Self)
|
||||
pub fn from_pem(pem: impl AsRef<[u8]>) -> Result<Self, Error> {
|
||||
tls::Certificate::from_pem(pem.as_ref())
|
||||
.map(Self)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ use reqwest::Method;
|
|||
|
||||
use super::{header, Client, Error, HttpError, StatusCode, Url};
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
pub use serde_json::Error as JsonError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RequestBuilder {
|
||||
pub(super) client: Client,
|
||||
|
@ -96,4 +99,13 @@ impl Response {
|
|||
pub fn headers(&self) -> &header::HeaderMap {
|
||||
self.inner.headers()
|
||||
}
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
pub async fn json<T>(self) -> Result<T, Error>
|
||||
where
|
||||
T: serde::de::DeserializeOwned,
|
||||
{
|
||||
let bytes = self.error_for_status()?.bytes().await?;
|
||||
Ok(serde_json::from_slice(&bytes)?)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue