#![warn(missing_docs)]
#![allow(clippy::redundant_closure)]
use anyhow::{Context, Error};
use semver::{Version, VersionReq};
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fs, path::Path};
use url::Url;
mod add;
mod init;
mod list;
mod lock;
mod metadata;
mod util;
mod validate;
mod yank;
pub use add::{add, add_from_crate, force_add};
pub use init::init;
pub use list::{list, list_all};
pub use metadata::{metadata, metadata_from_crate};
pub use validate::validate;
pub use yank::{set_yank, unyank, yank};
#[derive(Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct IndexPackage {
pub name: String,
pub vers: Version,
pub deps: Vec<IndexDependency>,
pub features: BTreeMap<String, Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub features2: Option<BTreeMap<String, Vec<String>>>,
pub cksum: String,
pub yanked: bool,
pub links: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub v: Option<u8>,
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct IndexDependency {
pub name: String,
pub req: VersionReq,
pub features: Vec<String>,
pub optional: bool,
pub default_features: bool,
pub target: Option<String>,
#[serde(default, deserialize_with = "parse_dependency_kind")]
pub kind: cargo_metadata::DependencyKind,
#[serde(default)]
pub registry: Option<Url>,
pub package: Option<String>,
}
fn parse_dependency_kind<'de, D>(d: D) -> Result<cargo_metadata::DependencyKind, D::Error>
where
D: serde::Deserializer<'de>,
{
serde::Deserialize::deserialize(d).map(|x: Option<_>| x.unwrap_or_default())
}
#[derive(Serialize, Deserialize)]
#[non_exhaustive]
pub struct IndexConfig {
pub dl: Url,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub api: Option<Url>,
}
pub fn load_config(index: impl AsRef<Path>) -> Result<IndexConfig, Error> {
let path = index.as_ref().join("config.json");
let f =
fs::File::open(&path).with_context(|| format!("Failed to open `{}`.", path.display()))?;
let index_cfg: IndexConfig = serde_json::from_reader(f)
.with_context(|| format!("Failed to deserialize `{}`.", path.display()))?;
Ok(index_cfg)
}