Refactor: Extract new crate binstalk-manifests (#511)

* Refactor: Extract new crate binstalk-manifests
* Fix clippy warning in mod `binstall_crates_v1`
* Rm unused deps in binstalk
* Update release-pr

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-11-08 11:50:02 +11:00 committed by GitHub
parent 565be9ae4c
commit fc6d9ab956
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 96 additions and 47 deletions

View file

@ -0,0 +1,148 @@
use std::{borrow::Cow, fmt, str::FromStr};
use compact_str::CompactString;
use miette::Diagnostic;
use semver::Version;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use thiserror::Error;
use url::Url;
use crate::{
crate_info::{CrateInfo, CrateSource, SourceType},
helpers::cratesio_url,
};
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub struct CrateVersionSource {
pub name: CompactString,
pub version: Version,
pub source: Source,
}
impl From<&CrateInfo> for CrateVersionSource {
fn from(metadata: &CrateInfo) -> Self {
super::CrateVersionSource {
name: metadata.name.clone(),
version: metadata.current_version.clone(),
source: Source::from(&metadata.source),
}
}
}
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum Source {
Git(Url),
Path(Url),
Registry(Url),
}
impl Source {
pub fn cratesio_registry() -> Source {
Self::Registry(cratesio_url().clone())
}
}
impl From<&CrateSource> for Source {
fn from(source: &CrateSource) -> Self {
use SourceType::*;
let url = source.url.clone();
match source.source_type {
Git => Self::Git(url),
Path => Self::Path(url),
Registry => Self::Registry(url),
}
}
}
impl FromStr for CrateVersionSource {
type Err = CvsParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.splitn(3, ' ').collect::<Vec<_>>()[..] {
[name, version, source] => {
let version = version.parse()?;
let source = match source
.trim_matches(&['(', ')'][..])
.splitn(2, '+')
.collect::<Vec<_>>()[..]
{
["git", url] => Source::Git(Url::parse(url)?),
["path", url] => Source::Path(Url::parse(url)?),
["registry", url] => Source::Registry(Url::parse(url)?),
[kind, arg] => {
return Err(CvsParseError::UnknownSourceType {
kind: kind.to_string(),
arg: arg.to_string(),
})
}
_ => return Err(CvsParseError::BadSource),
};
Ok(Self {
name: name.into(),
version,
source,
})
}
_ => Err(CvsParseError::BadFormat),
}
}
}
#[derive(Debug, Diagnostic, Error)]
pub enum CvsParseError {
#[error(transparent)]
UrlParse(#[from] url::ParseError),
#[error(transparent)]
VersionParse(#[from] semver::Error),
#[error("unknown source type {kind}+{arg}")]
UnknownSourceType { kind: String, arg: String },
#[error("bad source format")]
BadSource,
#[error("bad CVS format")]
BadFormat,
}
impl fmt::Display for CrateVersionSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self {
name,
version,
source,
} = &self;
write!(f, "{name} {version} ({source})")
}
}
impl fmt::Display for Source {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Source::Git(url) => write!(f, "git+{url}"),
Source::Path(url) => write!(f, "path+{url}"),
Source::Registry(url) => write!(f, "registry+{url}"),
}
}
}
impl Serialize for CrateVersionSource {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl<'de> Deserialize<'de> for CrateVersionSource {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = Cow::<'_, str>::deserialize(deserializer)?;
Self::from_str(&s).map_err(serde::de::Error::custom)
}
}