mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-05-13 15:30:03 +00:00
Write to .crates2.json
This commit is contained in:
parent
1c2d005fd4
commit
17cf6f5dc5
7 changed files with 296 additions and 188 deletions
111
src/metafiles/cvs.rs
Normal file
111
src/metafiles/cvs.rs
Normal file
|
@ -0,0 +1,111 @@
|
|||
use std::{fmt, str::FromStr};
|
||||
|
||||
use miette::Diagnostic;
|
||||
use semver::Version;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub struct CrateVersionSource {
|
||||
pub name: String,
|
||||
pub version: Version,
|
||||
pub source: Source,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub enum Source {
|
||||
Git(Url),
|
||||
Path(Url),
|
||||
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.to_string(),
|
||||
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>,
|
||||
{
|
||||
Self::from_str(&String::deserialize(deserializer)?).map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
67
src/metafiles/v1.rs
Normal file
67
src/metafiles/v1.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use miette::Diagnostic;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
use super::CrateVersionSource;
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct CratesToml {
|
||||
v1: BTreeMap<CrateVersionSource, BTreeSet<String>>,
|
||||
}
|
||||
|
||||
impl CratesToml {
|
||||
pub fn default_path() -> Result<PathBuf, CratesTomlParseError> {
|
||||
Ok(home::cargo_home()?.join(".crates.toml"))
|
||||
}
|
||||
|
||||
pub fn load() -> Result<Self, CratesTomlParseError> {
|
||||
Self::load_from_path(Self::default_path()?)
|
||||
}
|
||||
|
||||
pub fn load_from_path(path: impl AsRef<Path>) -> Result<Self, CratesTomlParseError> {
|
||||
let file = fs::read_to_string(path)?;
|
||||
Self::from_str(&file)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, cvs: CrateVersionSource, bins: BTreeSet<String>) {
|
||||
self.v1.insert(cvs, bins);
|
||||
}
|
||||
|
||||
pub fn write(&self) -> Result<(), CratesTomlParseError> {
|
||||
self.write_to_path(Self::default_path()?)
|
||||
}
|
||||
|
||||
pub fn write_to_path(&self, path: impl AsRef<Path>) -> Result<(), CratesTomlParseError> {
|
||||
fs::write(path, &toml::to_vec(&self)?)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for CratesToml {
|
||||
type Err = CratesTomlParseError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(toml::from_str(s)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Diagnostic, Error)]
|
||||
pub enum CratesTomlParseError {
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
TomlParse(#[from] toml::de::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
TomlWrite(#[from] toml::ser::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
CvsParse(#[from] super::CvsParseError),
|
||||
}
|
78
src/metafiles/v2.rs
Normal file
78
src/metafiles/v2.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use miette::Diagnostic;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
use super::CrateVersionSource;
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Crates2Json {
|
||||
pub installs: BTreeMap<CrateVersionSource, CrateInfo>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct CrateInfo {
|
||||
#[serde(default)]
|
||||
pub version_req: Option<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub bins: BTreeSet<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub features: BTreeSet<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub all_features: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub no_default_features: bool,
|
||||
|
||||
pub profile: String,
|
||||
pub target: String,
|
||||
pub rustc: String,
|
||||
}
|
||||
|
||||
impl Crates2Json {
|
||||
pub fn default_path() -> Result<PathBuf, Crates2JsonParseError> {
|
||||
Ok(home::cargo_home()?.join(".crates2.json"))
|
||||
}
|
||||
|
||||
pub fn load() -> Result<Self, Crates2JsonParseError> {
|
||||
Self::load_from_path(Self::default_path()?)
|
||||
}
|
||||
|
||||
pub fn load_from_path(path: impl AsRef<Path>) -> Result<Self, Crates2JsonParseError> {
|
||||
let file = fs::read_to_string(path)?;
|
||||
Ok(serde_json::from_str(&file)?)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, cvs: CrateVersionSource, info: CrateInfo) {
|
||||
self.installs.insert(cvs, info);
|
||||
}
|
||||
|
||||
pub fn write(&self) -> Result<(), Crates2JsonParseError> {
|
||||
self.write_to_path(Self::default_path()?)
|
||||
}
|
||||
|
||||
pub fn write_to_path(&self, path: impl AsRef<Path>) -> Result<(), Crates2JsonParseError> {
|
||||
fs::write(path, &serde_json::to_vec(&self)?)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Diagnostic, Error)]
|
||||
pub enum Crates2JsonParseError {
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Json(#[from] serde_json::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
CvsParse(#[from] super::CvsParseError),
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue