1use std::path::PathBuf;
2
3use rustc_hash::{FxHashMap, FxHashSet};
4use serde::{Deserialize, de::Deserializer};
5
6use crate::util::{RegexDef, Trie};
7
8#[derive(Clone, Debug, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct Manifest {
11 #[serde(skip_deserializing)]
12 pub manifest_dir: PathBuf,
13
14 #[serde(skip_deserializing)]
15 pub manifest_path: PathBuf,
16
17 #[serde(skip_deserializing)]
18 pub location_trie: Trie<PackageLocator>,
19
20 pub enable_top_level_fallback: bool,
21 pub ignore_pattern_data: Option<RegexDef>,
22
23 pub dependency_tree_roots: FxHashSet<PackageLocator>,
28
29 #[serde(deserialize_with = "deserialize_package_dependencies")]
34 pub fallback_pool: FxHashMap<String, Option<PackageDependency>>,
35
36 #[serde(deserialize_with = "deserialize_fallback_exclusion_list")]
41 pub fallback_exclusion_list: FxHashMap<String, FxHashSet<String>>,
42
43 #[serde(deserialize_with = "deserialize_package_registry_data")]
51 pub package_registry_data: FxHashMap<String, FxHashMap<String, PackageInformation>>,
52}
53
54#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Deserialize)]
55pub struct PackageLocator {
56 pub name: String,
57 pub reference: String,
58}
59
60#[derive(Clone, Debug, Deserialize)]
61#[serde(rename_all = "camelCase")]
62pub struct PackageInformation {
63 pub package_location: PathBuf,
64
65 #[serde(default)]
66 pub discard_from_lookup: bool,
67
68 #[serde(deserialize_with = "deserialize_package_dependencies")]
69 pub package_dependencies: FxHashMap<String, Option<PackageDependency>>,
70}
71
72#[derive(Clone, Debug, Deserialize)]
73#[serde(untagged)]
74pub enum PackageDependency {
75 Reference(String),
76 Alias(String, String),
77}
78
79fn deserialize_fallback_exclusion_list<'de, D>(
80 deserializer: D,
81) -> Result<FxHashMap<String, FxHashSet<String>>, D::Error>
82where
83 D: Deserializer<'de>,
84{
85 #[derive(Debug, Deserialize)]
86 struct Item(String, FxHashSet<String>);
87
88 let mut map = FxHashMap::default();
89 for item in Vec::<Item>::deserialize(deserializer)? {
90 map.insert(item.0, item.1);
91 }
92 Ok(map)
93}
94
95fn deserialize_package_dependencies<'de, D>(
96 deserializer: D,
97) -> Result<FxHashMap<String, Option<PackageDependency>>, D::Error>
98where
99 D: Deserializer<'de>,
100{
101 #[derive(Debug, Deserialize)]
102 struct Item(String, Option<PackageDependency>);
103
104 let mut map = FxHashMap::default();
105 for item in Vec::<Item>::deserialize(deserializer)? {
106 map.insert(item.0, item.1);
107 }
108 Ok(map)
109}
110
111fn deserialize_package_registry_data<'de, D>(
112 deserializer: D,
113) -> Result<FxHashMap<String, FxHashMap<String, PackageInformation>>, D::Error>
114where
115 D: Deserializer<'de>,
116{
117 #[derive(Debug, Deserialize)]
118 struct Item(Option<String>, Vec<(Option<String>, PackageInformation)>);
119
120 let mut map = FxHashMap::default();
121 for item in Vec::<Item>::deserialize(deserializer)? {
122 let key = item.0.unwrap_or_default();
123 let value =
124 FxHashMap::from_iter(item.1.into_iter().map(|(k, v)| (k.unwrap_or_default(), v)));
125 map.insert(key, value);
126 }
127 Ok(map)
128}