diff --git a/Cargo.lock b/Cargo.lock index 9ea25c8..c03b996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,33 +17,12 @@ dependencies = [ "memchr", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "bit-set" version = "0.8.0" @@ -71,12 +50,6 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - [[package]] name = "byteorder" version = "1.5.0" @@ -89,34 +62,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -[[package]] -name = "cc" -version = "1.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" -dependencies = [ - "shlex", -] - [[package]] name = "cfg-if" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" -[[package]] -name = "chrono" -version = "0.4.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "windows-link", -] - [[package]] name = "clean-path" version = "0.2.1" @@ -142,63 +93,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "deranged" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "dyn-clone" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" - [[package]] name = "endian-type" version = "0.1.2" @@ -234,12 +128,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "futures-core" version = "0.3.31" @@ -289,12 +177,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.15.4" @@ -307,53 +189,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "iana-time-zone" -version = "0.1.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - [[package]] name = "indexmap" version = "2.10.0" @@ -361,7 +196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown 0.15.4", + "hashbrown", "serde", ] @@ -371,28 +206,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - [[package]] name = "libc" version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - [[package]] name = "mach2" version = "0.4.3" @@ -465,21 +284,6 @@ dependencies = [ "pin-utils", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -518,7 +322,7 @@ dependencies = [ "clean-path", "concurrent_lru", "fancy-regex", - "indexmap 2.10.0", + "indexmap", "miniz_oxide", "mmap-rs", "path-slash", @@ -528,16 +332,9 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "serde_with", "thiserror 2.0.12", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -575,26 +372,6 @@ dependencies = [ "nibble_vec", ] -[[package]] -name = "ref-cast" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "regex" version = "1.11.1" @@ -675,12 +452,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustversion" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" - [[package]] name = "ryu" version = "1.0.20" @@ -696,18 +467,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schemars" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - [[package]] name = "semver" version = "1.0.26" @@ -746,43 +505,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf65a400f8f66fb7b0552869ad70157166676db75ed8181f8104ea91cf9d0b42" -dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.10.0", - "schemars", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81679d9ed988d5e9a5e6531dc3f2c28efbd639cbd1dfb628df08edea6004da77" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - [[package]] name = "slab" version = "0.4.10" @@ -795,12 +517,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "syn" version = "2.0.104" @@ -866,37 +582,6 @@ dependencies = [ "syn", ] -[[package]] -name = "time" -version = "0.3.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" - -[[package]] -name = "time-macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" -dependencies = [ - "num-conv", - "time-core", -] - [[package]] name = "toml_datetime" version = "0.6.11" @@ -909,7 +594,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.10.0", + "indexmap", "toml_datetime", "winnow", ] @@ -930,64 +615,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - [[package]] name = "widestring" version = "1.2.0" @@ -1012,65 +639,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index ecb4ae8..73b3ea1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ byteorder = "1" clean-path = "0.2.1" concurrent_lru = "^0.2" fancy-regex = { version = "^0.14.0", default-features = false, features = ["std"] } -indexmap = { version = "2", features = ["serde"] } +indexmap = { version = "2", default-features = true, features = ["serde"] } miniz_oxide = "^0.8" mmap-rs = { version = "^0.6", optional = true } path-slash = "0.2.1" @@ -20,7 +20,6 @@ pathdiff = "^0.2" radix_trie = "0.2.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -serde_with = { version = "3", features = ["indexmap_2"] } thiserror = "2" rustc-hash = "2" diff --git a/src/lib.rs b/src/lib.rs index 8536dbd..ca0a89c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,27 +2,24 @@ pub mod fs; mod builtins; mod error; +mod manifest; mod util; mod zip; use std::{ collections::hash_map::Entry, - hash::BuildHasherDefault, path::{Path, PathBuf}, sync::OnceLock, }; use fancy_regex::Regex; -use indexmap::IndexMap; -use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; -use serde::Deserialize; -use serde_with::{DefaultOnNull, serde_as}; -use crate::util::RegexDef; - -pub use crate::error::{ - BadSpecifier, Error, FailedManifestHydration, MissingDependency, MissingPeerDependency, - UndeclaredDependency, +pub use crate::{ + error::{ + BadSpecifier, Error, FailedManifestHydration, MissingDependency, MissingPeerDependency, + UndeclaredDependency, + }, + manifest::{Manifest, PackageDependency, PackageInformation, PackageLocator}, }; #[derive(Debug)] @@ -47,80 +44,6 @@ pub struct ResolutionConfig { pub host: ResolutionHost, } -#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq)] -pub struct PackageLocator { - name: String, - reference: String, -} - -#[derive(Clone, Debug, Deserialize)] -#[serde(untagged)] -enum PackageDependency { - Reference(String), - Alias(String, String), -} - -#[serde_as] -#[derive(Clone, Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct PackageInformation { - package_location: PathBuf, - - #[serde(default)] - discard_from_lookup: bool, - - #[serde_as(as = "Vec<(_, Option<_>)>")] - package_dependencies: FxHashMap>, -} - -#[serde_as] -#[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)] - location_trie: util::Trie, - - enable_top_level_fallback: bool, - ignore_pattern_data: Option, - - // dependencyTreeRoots: [{ - // "name": "@app/monorepo", - // "workspace:." - // }] - dependency_tree_roots: FxHashSet, - - // fallbackPool: [[ - // "@app/monorepo", - // "workspace:.", - // ]] - #[serde_as(as = "Vec<(_, _)>")] - fallback_pool: FxHashMap>, - - // fallbackExclusionList: [[ - // "@app/server", - // ["workspace:sources/server"], - // ]] - #[serde_as(as = "Vec<(_, _)>")] - fallback_exclusion_list: FxHashMap>, - - // packageRegistryData: [ - // [null, [ - // [null, { - // ... - // }] - // }] - // ] - #[serde_as(as = "Vec<(DefaultOnNull<_>, Vec<(DefaultOnNull<_>, _)>)>")] - package_registry_data: - FxHashMap>>, -} - fn parse_scoped_package_name(specifier: &str) -> Option<(String, Option)> { let mut segments = specifier.splitn(3, '/'); diff --git a/src/manifest.rs b/src/manifest.rs new file mode 100644 index 0000000..5c82a56 --- /dev/null +++ b/src/manifest.rs @@ -0,0 +1,135 @@ +use std::{hash::BuildHasherDefault, path::PathBuf}; + +use indexmap::IndexMap; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +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, + + pub enable_top_level_fallback: bool, + pub ignore_pattern_data: Option, + + // dependencyTreeRoots: [{ + // "name": "@app/monorepo", + // "workspace:." + // }] + pub dependency_tree_roots: FxHashSet, + + // fallbackPool: [[ + // "@app/monorepo", + // "workspace:.", + // ]] + #[serde(deserialize_with = "deserialize_package_dependencies")] + pub fallback_pool: FxHashMap>, + + // fallbackExclusionList: [[ + // "@app/server", + // ["workspace:sources/server"], + // ]] + #[serde(deserialize_with = "deserialize_fallback_exclusion_list")] + pub fallback_exclusion_list: FxHashMap>, + + // packageRegistryData: [ + // [null, [ + // [null, { + // ... + // }] + // }] + // ] + #[serde(deserialize_with = "deserialize_package_registry_data")] + pub package_registry_data: + FxHashMap>>, +} + +#[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>, +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(untagged)] +pub enum PackageDependency { + Reference(String), + Alias(String, String), +} + +fn deserialize_fallback_exclusion_list<'de, D>( + deserializer: D, +) -> Result>, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Debug, Deserialize)] + struct Item(String, FxHashSet); + + let mut map = FxHashMap::default(); + for item in Vec::::deserialize(deserializer)? { + map.insert(item.0, item.1); + } + Ok(map) +} + +fn deserialize_package_dependencies<'de, D>( + deserializer: D, +) -> Result>, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Debug, Deserialize)] + struct Item(String, Option); + + let mut map = FxHashMap::default(); + for item in Vec::::deserialize(deserializer)? { + map.insert(item.0, item.1); + } + Ok(map) +} + +#[expect(clippy::type_complexity)] +fn deserialize_package_registry_data<'de, D>( + deserializer: D, +) -> Result< + FxHashMap>>, + D::Error, +> +where + D: Deserializer<'de>, +{ + #[derive(Debug, Deserialize)] + struct Item(Option, Vec<(Option, PackageInformation)>); + + let mut map = FxHashMap::default(); + for item in Vec::::deserialize(deserializer)? { + let key = item.0.unwrap_or_else(|| "".to_string()); + let value = IndexMap::from_iter( + item.1.into_iter().map(|(k, v)| (k.unwrap_or_else(|| "".to_string()), v)), + ); + map.insert(key, value); + } + Ok(map) +}