use std::path::PathBuf;
use rustc_hash::{FxHashMap, FxHashSet};
use serde::{Deserialize, de::Deserializer};
use crate::util::{RegexDef, Trie};
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Manifest {
#[serde(skip_deserializing)]
pub manifest_dir: PathBuf,
#[serde(skip_deserializing)]
pub manifest_path: PathBuf,
#[serde(skip_deserializing)]
pub location_trie: Trie<PackageLocator>,
pub enable_top_level_fallback: bool,
pub ignore_pattern_data: Option<RegexDef>,
pub dependency_tree_roots: FxHashSet<PackageLocator>,
#[serde(deserialize_with = "deserialize_package_dependencies")]
pub fallback_pool: FxHashMap<String, Option<PackageDependency>>,
#[serde(deserialize_with = "deserialize_fallback_exclusion_list")]
pub fallback_exclusion_list: FxHashMap<String, FxHashSet<String>>,
#[serde(deserialize_with = "deserialize_package_registry_data")]
pub package_registry_data: FxHashMap<String, FxHashMap<String, PackageInformation>>,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Deserialize)]
pub struct PackageLocator {
pub name: String,
pub reference: String,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PackageInformation {
pub package_location: PathBuf,
#[serde(default)]
pub discard_from_lookup: bool,
#[serde(deserialize_with = "deserialize_package_dependencies")]
pub package_dependencies: FxHashMap<String, Option<PackageDependency>>,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
pub enum PackageDependency {
Reference(String),
Alias(String, String),
}
fn deserialize_fallback_exclusion_list<'de, D>(
deserializer: D,
) -> Result<FxHashMap<String, FxHashSet<String>>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
struct Item(String, FxHashSet<String>);
let mut map = FxHashMap::default();
for item in Vec::<Item>::deserialize(deserializer)? {
map.insert(item.0, item.1);
}
Ok(map)
}
fn deserialize_package_dependencies<'de, D>(
deserializer: D,
) -> Result<FxHashMap<String, Option<PackageDependency>>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
struct Item(String, Option<PackageDependency>);
let mut map = FxHashMap::default();
for item in Vec::<Item>::deserialize(deserializer)? {
map.insert(item.0, item.1);
}
Ok(map)
}
fn deserialize_package_registry_data<'de, D>(
deserializer: D,
) -> Result<FxHashMap<String, FxHashMap<String, PackageInformation>>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
struct Item(Option<String>, Vec<(Option<String>, PackageInformation)>);
let mut map = FxHashMap::default();
for item in Vec::<Item>::deserialize(deserializer)? {
let key = item.0.unwrap_or_default();
let value =
FxHashMap::from_iter(item.1.into_iter().map(|(k, v)| (k.unwrap_or_default(), v)));
map.insert(key, value);
}
Ok(map)
}