aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-core/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-11 02:05:34 +0900
committernsfisis <nsfisis@gmail.com>2026-05-11 02:05:34 +0900
commit4df5f8491320e5795718cf0222e80fa27e57c8ad (patch)
tree707e19f34dbdef18490ec3245d34389e3d189a57 /crates/mozart-core/src
parent8871b923fa3df1935c263db155cb8bc3d59705cd (diff)
downloadphp-mozart-4df5f8491320e5795718cf0222e80fa27e57c8ad.tar.gz
php-mozart-4df5f8491320e5795718cf0222e80fa27e57c8ad.tar.zst
php-mozart-4df5f8491320e5795718cf0222e80fa27e57c8ad.zip
refactor(package): rename traits and switch dep maps to IndexMap
Rename Package/CompletePackage to PackageInterface/CompletePackageInterface to mirror Composer's interface names, and split each into its own module under crates/mozart-core/src/package/. Switch dependency-link and metadata maps from BTreeMap to indexmap::IndexMap so serialized JSON preserves the original key ordering rather than sorting alphabetically — matching PHP associative-array semantics. The --sort-packages behaviour in `require` is preserved via sort_unstable_keys.
Diffstat (limited to 'crates/mozart-core/src')
-rw-r--r--crates/mozart-core/src/autoload.rs66
-rw-r--r--crates/mozart-core/src/installer/installed_repo.rs9
-rw-r--r--crates/mozart-core/src/package.rs252
-rw-r--r--crates/mozart-core/src/package/complete_package_interface.rs17
-rw-r--r--crates/mozart-core/src/package/package_interface.rs33
-rw-r--r--crates/mozart-core/src/repository/browse_repos.rs19
-rw-r--r--crates/mozart-core/src/repository/installed.rs5
-rw-r--r--crates/mozart-core/src/repository/lockfile.rs160
-rw-r--r--crates/mozart-core/src/repository/packagist.rs20
-rw-r--r--crates/mozart-core/src/repository/vcs_bridge.rs3
-rw-r--r--crates/mozart-core/src/repository_utils.rs19
11 files changed, 300 insertions, 303 deletions
diff --git a/crates/mozart-core/src/autoload.rs b/crates/mozart-core/src/autoload.rs
index 7e8ead6..08a2859 100644
--- a/crates/mozart-core/src/autoload.rs
+++ b/crates/mozart-core/src/autoload.rs
@@ -8,7 +8,6 @@ use crate::repository::installed::InstalledPackages;
use crate::repository::lockfile::LockedPackage;
use indexmap::IndexSet;
use mozart_class_map_generator::{scan_classmap_dirs, scan_psr_for_classmap};
-use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
// Embed Composer PHP files from the submodule at compile time.
@@ -70,15 +69,15 @@ pub struct AutoloadConfig {
pub struct AutoloadData {
/// PSR-4: namespace prefix -> list of directory path expressions.
/// Each path is a PHP expression string like `$vendorDir . '/psr/log/src'`.
- pub psr4: BTreeMap<String, Vec<String>>,
+ pub psr4: indexmap::IndexMap<String, Vec<String>>,
/// PSR-0: namespace prefix -> list of directory path expressions.
/// (Empty in Phase 2.2, populated in 5.6.)
- pub psr0: BTreeMap<String, Vec<String>>,
+ pub psr0: indexmap::IndexMap<String, Vec<String>>,
/// Classmap entries: class name -> file path expression.
/// (Empty in Phase 2.2, populated in 5.6.)
- pub classmap: BTreeMap<String, String>,
+ pub classmap: indexmap::IndexMap<String, String>,
/// Files to include on every request: file_identifier -> path expression.
- pub files: BTreeMap<String, String>,
+ pub files: indexmap::IndexMap<String, String>,
}
/// Mirror of `Composer\ClassMapGenerator\ClassMap` — the return value
@@ -92,9 +91,9 @@ pub struct AutoloadData {
/// summary — once `generate` is refactored to expose the full classmap
/// these fields will hold the real entries.
pub struct ClassMap {
- map: BTreeMap<String, String>,
+ map: indexmap::IndexMap<String, String>,
psr_violations: Vec<String>,
- ambiguous_classes: BTreeMap<String, Vec<String>>,
+ ambiguous_classes: indexmap::IndexMap<String, Vec<String>>,
}
impl ClassMap {
@@ -126,7 +125,7 @@ impl ClassMap {
}
/// Read access to the underlying map (`getMap()` upstream).
- pub fn map(&self) -> &BTreeMap<String, String> {
+ pub fn map(&self) -> &indexmap::IndexMap<String, String> {
&self.map
}
@@ -136,7 +135,7 @@ impl ClassMap {
}
/// Read access to the ambiguous-class records.
- pub fn ambiguous_classes(&self) -> &BTreeMap<String, Vec<String>> {
+ pub fn ambiguous_classes(&self) -> &indexmap::IndexMap<String, Vec<String>> {
&self.ambiguous_classes
}
}
@@ -282,9 +281,9 @@ impl AutoloadGeneratorExt for AutoloadGenerator {
// for now and surface the limitation here rather than
// silently writing files.
return Ok(ClassMap {
- map: BTreeMap::new(),
+ map: indexmap::IndexMap::new(),
psr_violations: Vec::new(),
- ambiguous_classes: BTreeMap::new(),
+ ambiguous_classes: indexmap::IndexMap::new(),
});
}
@@ -297,7 +296,7 @@ impl AutoloadGeneratorExt for AutoloadGenerator {
// command code that only branches on `count()` / `has_*()` works
// today; refactoring `generate` to surface the full map is
// tracked as follow-up work.
- let mut map = BTreeMap::new();
+ let mut map = indexmap::IndexMap::new();
for i in 0..result.class_count {
map.insert(format!("__mozart_placeholder_{i}"), String::new());
}
@@ -308,7 +307,7 @@ impl AutoloadGeneratorExt for AutoloadGenerator {
} else {
Vec::new()
};
- let mut ambiguous_classes = BTreeMap::new();
+ let mut ambiguous_classes = indexmap::IndexMap::new();
if result.has_ambiguous_classes {
ambiguous_classes.insert("__mozart_placeholder".to_string(), Vec::new());
}
@@ -526,16 +525,16 @@ fn collect_autoloads(
dev_mode: bool,
) -> (AutoloadData, AutoloadData) {
let mut data = AutoloadData {
- psr4: BTreeMap::new(),
- psr0: BTreeMap::new(),
- classmap: BTreeMap::new(),
- files: BTreeMap::new(),
+ psr4: indexmap::IndexMap::new(),
+ psr0: indexmap::IndexMap::new(),
+ classmap: indexmap::IndexMap::new(),
+ files: indexmap::IndexMap::new(),
};
let mut static_data = AutoloadData {
- psr4: BTreeMap::new(),
- psr0: BTreeMap::new(),
- classmap: BTreeMap::new(),
- files: BTreeMap::new(),
+ psr4: indexmap::IndexMap::new(),
+ psr0: indexmap::IndexMap::new(),
+ classmap: indexmap::IndexMap::new(),
+ files: indexmap::IndexMap::new(),
};
// Process each installed package
@@ -703,7 +702,7 @@ fn generate_autoload_static(static_data: &AutoloadData, suffix: &str) -> String
// $prefixLengthsPsr4 — group by first character of namespace
if !static_data.psr4.is_empty() {
// Group namespaces by first character, sorted reverse
- let mut by_char: BTreeMap<char, Vec<(&String, usize)>> = BTreeMap::new();
+ let mut by_char: indexmap::IndexMap<_, Vec<_>> = indexmap::IndexMap::new();
let mut sorted_ns: Vec<&String> = static_data.psr4.keys().collect();
sorted_ns.sort_by(|a, b| b.cmp(a));
@@ -1278,11 +1277,11 @@ pub fn generate(config: &AutoloadConfig) -> anyhow::Result<GenerateResult> {
version_normalized: p.version_normalized.clone(),
source: None,
dist: None,
- require: std::collections::BTreeMap::new(),
- require_dev: std::collections::BTreeMap::new(),
- conflict: std::collections::BTreeMap::new(),
- provide: std::collections::BTreeMap::new(),
- replace: std::collections::BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ require_dev: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
suggest: None,
package_type: p.package_type.clone(),
autoload: p.autoload.clone(),
@@ -1295,7 +1294,7 @@ pub fn generate(config: &AutoloadConfig) -> anyhow::Result<GenerateResult> {
support: None,
funding: None,
time: None,
- extra_fields: std::collections::BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
})
.collect()
};
@@ -1370,7 +1369,6 @@ pub fn generate(config: &AutoloadConfig) -> anyhow::Result<GenerateResult> {
mod tests {
use super::*;
use crate::repository::installed::{InstalledPackageEntry, InstalledPackages};
- use std::collections::BTreeMap;
use tempfile::tempdir;
fn make_installed_pkg(name: &str, version: &str) -> InstalledPackageEntry {
@@ -1386,7 +1384,7 @@ mod tests {
aliases: vec![],
homepage: None,
support: None,
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
}
}
@@ -1589,10 +1587,10 @@ mod tests {
#[test]
fn test_generate_autoload_psr4_empty() {
let data = AutoloadData {
- psr4: BTreeMap::new(),
- psr0: BTreeMap::new(),
- classmap: BTreeMap::new(),
- files: BTreeMap::new(),
+ psr4: indexmap::IndexMap::new(),
+ psr0: indexmap::IndexMap::new(),
+ classmap: indexmap::IndexMap::new(),
+ files: indexmap::IndexMap::new(),
};
let output = generate_autoload_psr4(&data);
assert!(output.contains("return array(\n);"));
diff --git a/crates/mozart-core/src/installer/installed_repo.rs b/crates/mozart-core/src/installer/installed_repo.rs
index 8361158..d7e4f83 100644
--- a/crates/mozart-core/src/installer/installed_repo.rs
+++ b/crates/mozart-core/src/installer/installed_repo.rs
@@ -17,7 +17,6 @@
//! or through a `provide` / `replace` link.
use indexmap::IndexSet;
-use std::collections::BTreeMap;
/// One installed package, in the shape `findPackagesWithReplacersAndProviders`
/// needs. Mirrors the fields of `Composer\Package\PackageInterface` that the
@@ -33,9 +32,9 @@ pub struct InstalledCandidate {
/// Original-case version, used in user-facing output.
pub pretty_version: String,
/// `provide` map: target package name → constraint string.
- pub provides: BTreeMap<String, String>,
+ pub provides: indexmap::IndexMap<String, String>,
/// `replace` map: target package name → constraint string.
- pub replaces: BTreeMap<String, String>,
+ pub replaces: indexmap::IndexMap<String, String>,
}
#[derive(Debug, Clone, Default)]
@@ -106,8 +105,8 @@ mod tests {
pretty_name: name.to_string(),
version: version.to_string(),
pretty_version: version.to_string(),
- provides: BTreeMap::new(),
- replaces: BTreeMap::new(),
+ provides: indexmap::IndexMap::new(),
+ replaces: indexmap::IndexMap::new(),
}
}
diff --git a/crates/mozart-core/src/package.rs b/crates/mozart-core/src/package.rs
index c6a3ae9..de88ffc 100644
--- a/crates/mozart-core/src/package.rs
+++ b/crates/mozart-core/src/package.rs
@@ -1,14 +1,18 @@
use serde::de::{Deserializer, MapAccess, SeqAccess, Visitor};
use serde::{Deserialize, Serialize};
-use std::collections::BTreeMap;
use std::fmt;
use std::fs;
use std::path::Path;
pub mod archiver;
+mod complete_package_interface;
pub mod dumper;
+mod package_interface;
pub mod version;
+pub use complete_package_interface::*;
+pub use package_interface::*;
+
/// Package stability level.
/// Higher value = less stable.
/// Corresponds to `Composer\Package\BasePackage::STABILITY_*`.
@@ -62,8 +66,8 @@ pub struct Author {
/// Autoload rule sets (PSR-4, PSR-0, classmap, files).
#[derive(Debug, Clone, Default)]
pub struct AutoloadRules {
- pub psr4: BTreeMap<String, Vec<String>>,
- pub psr0: BTreeMap<String, Vec<String>>,
+ pub psr4: indexmap::IndexMap<String, Vec<String>>,
+ pub psr0: indexmap::IndexMap<String, Vec<String>>,
pub classmap: Vec<String>,
pub files: Vec<String>,
}
@@ -125,19 +129,19 @@ pub struct PackageData {
pub dist_sha1_checksum: Option<String>,
pub release_date: Option<String>,
- pub extra: BTreeMap<String, serde_json::Value>,
+ pub extra: indexmap::IndexMap<String, serde_json::Value>,
pub binaries: Vec<String>,
pub dev: bool,
pub stability: Stability,
pub notification_url: Option<String>,
// dependency links
- pub requires: BTreeMap<String, Link>,
- pub conflicts: BTreeMap<String, Link>,
- pub provides: BTreeMap<String, Link>,
- pub replaces: BTreeMap<String, Link>,
- pub dev_requires: BTreeMap<String, Link>,
- pub suggests: BTreeMap<String, String>,
+ pub requires: indexmap::IndexMap<String, Link>,
+ pub conflicts: indexmap::IndexMap<String, Link>,
+ pub provides: indexmap::IndexMap<String, Link>,
+ pub replaces: indexmap::IndexMap<String, Link>,
+ pub dev_requires: indexmap::IndexMap<String, Link>,
+ pub suggests: indexmap::IndexMap<String, String>,
// autoload
pub autoload: AutoloadRules,
@@ -157,7 +161,7 @@ pub struct CompletePackageData {
pub license: Vec<String>,
pub keywords: Vec<String>,
pub authors: Vec<Author>,
- pub scripts: BTreeMap<String, Vec<String>>,
+ pub scripts: indexmap::IndexMap<String, Vec<String>>,
pub support: Support,
pub funding: Vec<Funding>,
pub repositories: Vec<serde_json::Value>,
@@ -175,105 +179,55 @@ pub struct RootPackageData {
pub minimum_stability: Stability,
pub prefer_stable: bool,
- pub stability_flags: BTreeMap<String, Stability>,
- pub config: BTreeMap<String, serde_json::Value>,
- pub references: BTreeMap<String, String>,
+ pub stability_flags: indexmap::IndexMap<String, Stability>,
+ pub config: indexmap::IndexMap<String, serde_json::Value>,
+ pub references: indexmap::IndexMap<String, String>,
pub aliases: Vec<VersionAlias>,
}
-/// Accessor for `PackageData` fields.
-/// Corresponds to `Composer\Package\PackageInterface`.
-pub trait Package {
- fn name(&self) -> &str;
- fn pretty_name(&self) -> &str;
- fn version(&self) -> &str;
- fn pretty_version(&self) -> &str;
- fn package_type(&self) -> &str;
- fn target_dir(&self) -> Option<&str>;
- fn source_type(&self) -> Option<&str>;
- fn source_url(&self) -> Option<&str>;
- fn source_reference(&self) -> Option<&str>;
- fn dist_type(&self) -> Option<&str>;
- fn dist_url(&self) -> Option<&str>;
- fn dist_reference(&self) -> Option<&str>;
- fn dist_sha1_checksum(&self) -> Option<&str>;
- fn release_date(&self) -> Option<&str>;
- fn extra(&self) -> &BTreeMap<String, serde_json::Value>;
- fn binaries(&self) -> &[String];
- fn is_dev(&self) -> bool;
- fn stability(&self) -> Stability;
- fn notification_url(&self) -> Option<&str>;
- fn requires(&self) -> &BTreeMap<String, Link>;
- fn conflicts(&self) -> &BTreeMap<String, Link>;
- fn provides(&self) -> &BTreeMap<String, Link>;
- fn replaces(&self) -> &BTreeMap<String, Link>;
- fn dev_requires(&self) -> &BTreeMap<String, Link>;
- fn suggests(&self) -> &BTreeMap<String, String>;
- fn autoload(&self) -> &AutoloadRules;
- fn dev_autoload(&self) -> &AutoloadRules;
- fn is_default_branch(&self) -> bool;
-}
-
-/// Accessor for `CompletePackageData` fields.
-/// Corresponds to `Composer\Package\CompletePackageInterface`.
-pub trait CompletePackage: Package {
- fn description(&self) -> Option<&str>;
- fn homepage(&self) -> Option<&str>;
- fn license(&self) -> &[String];
- fn keywords(&self) -> &[String];
- fn authors(&self) -> &[Author];
- fn scripts(&self) -> &BTreeMap<String, Vec<String>>;
- fn support(&self) -> &Support;
- fn funding(&self) -> &[Funding];
- fn repositories(&self) -> &[serde_json::Value];
- fn abandoned(&self) -> Option<&str>;
- fn archive_name(&self) -> Option<&str>;
- fn archive_excludes(&self) -> &[String];
-}
-
/// Accessor for `RootPackageData` fields.
/// Corresponds to `Composer\Package\RootPackageInterface`.
-pub trait RootPackage: CompletePackage {
+pub trait RootPackage: CompletePackageInterface {
fn minimum_stability(&self) -> Stability;
fn prefer_stable(&self) -> bool;
- fn stability_flags(&self) -> &BTreeMap<String, Stability>;
- fn config(&self) -> &BTreeMap<String, serde_json::Value>;
- fn references(&self) -> &BTreeMap<String, String>;
+ fn stability_flags(&self) -> &indexmap::IndexMap<String, Stability>;
+ fn config(&self) -> &indexmap::IndexMap<String, serde_json::Value>;
+ fn references(&self) -> &indexmap::IndexMap<String, String>;
fn aliases(&self) -> &[VersionAlias];
}
/// Implements `Package` trait by delegating to an inner `PackageData` field.
macro_rules! delegate_package {
($type:ty => $($path:ident).+) => {
- impl Package for $type {
- fn name(&self) -> &str { &self.$($path).+.name }
- fn pretty_name(&self) -> &str { &self.$($path).+.pretty_name }
- fn version(&self) -> &str { &self.$($path).+.version }
- fn pretty_version(&self) -> &str { &self.$($path).+.pretty_version }
- fn package_type(&self) -> &str { &self.$($path).+.package_type }
- fn target_dir(&self) -> Option<&str> { self.$($path).+.target_dir.as_deref() }
- fn source_type(&self) -> Option<&str> { self.$($path).+.source_type.as_deref() }
- fn source_url(&self) -> Option<&str> { self.$($path).+.source_url.as_deref() }
- fn source_reference(&self) -> Option<&str> { self.$($path).+.source_reference.as_deref() }
- fn dist_type(&self) -> Option<&str> { self.$($path).+.dist_type.as_deref() }
- fn dist_url(&self) -> Option<&str> { self.$($path).+.dist_url.as_deref() }
- fn dist_reference(&self) -> Option<&str> { self.$($path).+.dist_reference.as_deref() }
- fn dist_sha1_checksum(&self) -> Option<&str> { self.$($path).+.dist_sha1_checksum.as_deref() }
- fn release_date(&self) -> Option<&str> { self.$($path).+.release_date.as_deref() }
- fn extra(&self) -> &BTreeMap<String, serde_json::Value> { &self.$($path).+.extra }
- fn binaries(&self) -> &[String] { &self.$($path).+.binaries }
- fn is_dev(&self) -> bool { self.$($path).+.dev }
- fn stability(&self) -> Stability { self.$($path).+.stability }
- fn notification_url(&self) -> Option<&str> { self.$($path).+.notification_url.as_deref() }
- fn requires(&self) -> &BTreeMap<String, Link> { &self.$($path).+.requires }
- fn conflicts(&self) -> &BTreeMap<String, Link> { &self.$($path).+.conflicts }
- fn provides(&self) -> &BTreeMap<String, Link> { &self.$($path).+.provides }
- fn replaces(&self) -> &BTreeMap<String, Link> { &self.$($path).+.replaces }
- fn dev_requires(&self) -> &BTreeMap<String, Link> { &self.$($path).+.dev_requires }
- fn suggests(&self) -> &BTreeMap<String, String> { &self.$($path).+.suggests }
- fn autoload(&self) -> &AutoloadRules { &self.$($path).+.autoload }
- fn dev_autoload(&self) -> &AutoloadRules { &self.$($path).+.dev_autoload }
- fn is_default_branch(&self) -> bool { self.$($path).+.is_default_branch }
+ impl PackageInterface for $type {
+ fn name(&self) -> &str { &self.$($path).+.name }
+ fn pretty_name(&self) -> &str { &self.$($path).+.pretty_name }
+ fn version(&self) -> &str { &self.$($path).+.version }
+ fn pretty_version(&self) -> &str { &self.$($path).+.pretty_version }
+ fn package_type(&self) -> &str { &self.$($path).+.package_type }
+ fn target_dir(&self) -> Option<&str> { self.$($path).+.target_dir.as_deref() }
+ fn source_type(&self) -> Option<&str> { self.$($path).+.source_type.as_deref() }
+ fn source_url(&self) -> Option<&str> { self.$($path).+.source_url.as_deref() }
+ fn source_reference(&self) -> Option<&str> { self.$($path).+.source_reference.as_deref() }
+ fn dist_type(&self) -> Option<&str> { self.$($path).+.dist_type.as_deref() }
+ fn dist_url(&self) -> Option<&str> { self.$($path).+.dist_url.as_deref() }
+ fn dist_reference(&self) -> Option<&str> { self.$($path).+.dist_reference.as_deref() }
+ fn dist_sha1_checksum(&self) -> Option<&str> { self.$($path).+.dist_sha1_checksum.as_deref() }
+ fn release_date(&self) -> Option<&str> { self.$($path).+.release_date.as_deref() }
+ fn extra(&self) -> &indexmap::IndexMap<String, serde_json::Value> { &self.$($path).+.extra }
+ fn binaries(&self) -> &[String] { &self.$($path).+.binaries }
+ fn is_dev(&self) -> bool { self.$($path).+.dev }
+ fn stability(&self) -> Stability { self.$($path).+.stability }
+ fn notification_url(&self) -> Option<&str> { self.$($path).+.notification_url.as_deref() }
+ fn requires(&self) -> &indexmap::IndexMap<String, Link> { &self.$($path).+.requires }
+ fn conflicts(&self) -> &indexmap::IndexMap<String, Link> { &self.$($path).+.conflicts }
+ fn provides(&self) -> &indexmap::IndexMap<String, Link> { &self.$($path).+.provides }
+ fn replaces(&self) -> &indexmap::IndexMap<String, Link> { &self.$($path).+.replaces }
+ fn dev_requires(&self) -> &indexmap::IndexMap<String, Link> { &self.$($path).+.dev_requires }
+ fn suggests(&self) -> &indexmap::IndexMap<String, String> { &self.$($path).+.suggests }
+ fn autoload(&self) -> &AutoloadRules { &self.$($path).+.autoload }
+ fn dev_autoload(&self) -> &AutoloadRules { &self.$($path).+.dev_autoload }
+ fn is_default_branch(&self) -> bool { self.$($path).+.is_default_branch }
}
};
}
@@ -281,24 +235,24 @@ macro_rules! delegate_package {
/// Implements `CompletePackage` trait by delegating to an inner `CompletePackageData` field.
macro_rules! delegate_complete_package {
($type:ty => $($path:ident).+) => {
- impl CompletePackage for $type {
- fn description(&self) -> Option<&str> { self.$($path).+.description.as_deref() }
- fn homepage(&self) -> Option<&str> { self.$($path).+.homepage.as_deref() }
- fn license(&self) -> &[String] { &self.$($path).+.license }
- fn keywords(&self) -> &[String] { &self.$($path).+.keywords }
- fn authors(&self) -> &[Author] { &self.$($path).+.authors }
- fn scripts(&self) -> &BTreeMap<String, Vec<String>> { &self.$($path).+.scripts }
- fn support(&self) -> &Support { &self.$($path).+.support }
- fn funding(&self) -> &[Funding] { &self.$($path).+.funding }
- fn repositories(&self) -> &[serde_json::Value] { &self.$($path).+.repositories }
- fn abandoned(&self) -> Option<&str> { self.$($path).+.abandoned.as_deref() }
- fn archive_name(&self) -> Option<&str> { self.$($path).+.archive_name.as_deref() }
- fn archive_excludes(&self) -> &[String] { &self.$($path).+.archive_excludes }
+ impl CompletePackageInterface for $type {
+ fn description(&self) -> Option<&str> { self.$($path).+.description.as_deref() }
+ fn homepage(&self) -> Option<&str> { self.$($path).+.homepage.as_deref() }
+ fn license(&self) -> &[String] { &self.$($path).+.license }
+ fn keywords(&self) -> &[String] { &self.$($path).+.keywords }
+ fn authors(&self) -> &[Author] { &self.$($path).+.authors }
+ fn scripts(&self) -> &indexmap::IndexMap<String, Vec<String>> { &self.$($path).+.scripts }
+ fn support(&self) -> &Support { &self.$($path).+.support }
+ fn funding(&self) -> &[Funding] { &self.$($path).+.funding }
+ fn repositories(&self) -> &[serde_json::Value] { &self.$($path).+.repositories }
+ fn abandoned(&self) -> Option<&str> { self.$($path).+.abandoned.as_deref() }
+ fn archive_name(&self) -> Option<&str> { self.$($path).+.archive_name.as_deref() }
+ fn archive_excludes(&self) -> &[String] { &self.$($path).+.archive_excludes }
}
};
}
-impl Package for PackageData {
+impl PackageInterface for PackageData {
fn name(&self) -> &str {
&self.name
}
@@ -341,7 +295,7 @@ impl Package for PackageData {
fn release_date(&self) -> Option<&str> {
self.release_date.as_deref()
}
- fn extra(&self) -> &BTreeMap<String, serde_json::Value> {
+ fn extra(&self) -> &indexmap::IndexMap<String, serde_json::Value> {
&self.extra
}
fn binaries(&self) -> &[String] {
@@ -356,22 +310,22 @@ impl Package for PackageData {
fn notification_url(&self) -> Option<&str> {
self.notification_url.as_deref()
}
- fn requires(&self) -> &BTreeMap<String, Link> {
+ fn requires(&self) -> &indexmap::IndexMap<String, Link> {
&self.requires
}
- fn conflicts(&self) -> &BTreeMap<String, Link> {
+ fn conflicts(&self) -> &indexmap::IndexMap<String, Link> {
&self.conflicts
}
- fn provides(&self) -> &BTreeMap<String, Link> {
+ fn provides(&self) -> &indexmap::IndexMap<String, Link> {
&self.provides
}
- fn replaces(&self) -> &BTreeMap<String, Link> {
+ fn replaces(&self) -> &indexmap::IndexMap<String, Link> {
&self.replaces
}
- fn dev_requires(&self) -> &BTreeMap<String, Link> {
+ fn dev_requires(&self) -> &indexmap::IndexMap<String, Link> {
&self.dev_requires
}
- fn suggests(&self) -> &BTreeMap<String, String> {
+ fn suggests(&self) -> &indexmap::IndexMap<String, String> {
&self.suggests
}
fn autoload(&self) -> &AutoloadRules {
@@ -385,7 +339,7 @@ impl Package for PackageData {
}
}
-impl CompletePackage for CompletePackageData {
+impl CompletePackageInterface for CompletePackageData {
fn description(&self) -> Option<&str> {
self.description.as_deref()
}
@@ -401,7 +355,7 @@ impl CompletePackage for CompletePackageData {
fn authors(&self) -> &[Author] {
&self.authors
}
- fn scripts(&self) -> &BTreeMap<String, Vec<String>> {
+ fn scripts(&self) -> &indexmap::IndexMap<String, Vec<String>> {
&self.scripts
}
fn support(&self) -> &Support {
@@ -431,13 +385,13 @@ impl RootPackage for RootPackageData {
fn prefer_stable(&self) -> bool {
self.prefer_stable
}
- fn stability_flags(&self) -> &BTreeMap<String, Stability> {
+ fn stability_flags(&self) -> &indexmap::IndexMap<String, Stability> {
&self.stability_flags
}
- fn config(&self) -> &BTreeMap<String, serde_json::Value> {
+ fn config(&self) -> &indexmap::IndexMap<String, serde_json::Value> {
&self.config
}
- fn references(&self) -> &BTreeMap<String, String> {
+ fn references(&self) -> &indexmap::IndexMap<String, String> {
&self.references
}
fn aliases(&self) -> &[VersionAlias] {
@@ -489,23 +443,23 @@ pub struct RawPackageData {
pub minimum_stability: Option<String>,
#[serde(default)]
- pub require: BTreeMap<String, String>,
+ pub require: indexmap::IndexMap<String, String>,
#[serde(
rename = "require-dev",
default,
- skip_serializing_if = "BTreeMap::is_empty"
+ skip_serializing_if = "indexmap::IndexMap::is_empty"
)]
- pub require_dev: BTreeMap<String, String>,
+ pub require_dev: indexmap::IndexMap<String, String>,
- #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
- pub conflict: BTreeMap<String, String>,
+ #[serde(default, skip_serializing_if = "indexmap::IndexMap::is_empty")]
+ pub conflict: indexmap::IndexMap<String, String>,
- #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
- pub provide: BTreeMap<String, String>,
+ #[serde(default, skip_serializing_if = "indexmap::IndexMap::is_empty")]
+ pub provide: indexmap::IndexMap<String, String>,
- #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
- pub replace: BTreeMap<String, String>,
+ #[serde(default, skip_serializing_if = "indexmap::IndexMap::is_empty")]
+ pub replace: indexmap::IndexMap<String, String>,
/// `repositories` accepts either a JSON array or a JSON object keyed by
/// repository name. Composer iterates `foreach ($repoConfigs as ...)` in
@@ -525,7 +479,7 @@ pub struct RawPackageData {
pub bin: Vec<String>,
#[serde(flatten)]
- pub extra_fields: BTreeMap<String, serde_json::Value>,
+ pub extra_fields: indexmap::IndexMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -539,7 +493,7 @@ pub struct RawAuthor {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RawAutoload {
#[serde(rename = "psr-4")]
- pub psr4: BTreeMap<String, String>,
+ pub psr4: indexmap::IndexMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -653,15 +607,15 @@ impl RawPackageData {
license: None,
authors: Vec::new(),
minimum_stability: None,
- require: BTreeMap::new(),
- require_dev: BTreeMap::new(),
- conflict: BTreeMap::new(),
- provide: BTreeMap::new(),
- replace: BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ require_dev: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
repositories: Vec::new(),
autoload: None,
bin: Vec::new(),
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
}
}
@@ -696,9 +650,9 @@ impl RootPackageData {
pub fn from_raw(raw: RawPackageData) -> Self {
fn make_links(
source: &str,
- deps: BTreeMap<String, String>,
+ deps: indexmap::IndexMap<String, String>,
description: &str,
- ) -> BTreeMap<String, Link> {
+ ) -> indexmap::IndexMap<String, Link> {
deps.into_iter()
.map(|(target, constraint)| {
let normalized = target.to_lowercase();
@@ -745,7 +699,7 @@ impl RootPackageData {
})
.unwrap_or_default();
- let extra: BTreeMap<String, serde_json::Value> = raw
+ let extra: indexmap::IndexMap<String, serde_json::Value> = raw
.extra_fields
.get("extra")
.and_then(|v| v.as_object())
@@ -783,7 +737,7 @@ impl RootPackageData {
})
.unwrap_or_default();
- let scripts: BTreeMap<String, Vec<String>> = raw
+ let scripts: indexmap::IndexMap<String, Vec<String>> = raw
.extra_fields
.get("scripts")
.and_then(|v| v.as_object())
@@ -841,7 +795,7 @@ impl RootPackageData {
})
.unwrap_or_default();
- let config: BTreeMap<String, serde_json::Value> = raw
+ let config: indexmap::IndexMap<String, serde_json::Value> = raw
.extra_fields
.get("config")
.and_then(|v| v.as_object())
@@ -882,7 +836,7 @@ impl RootPackageData {
provides,
replaces,
dev_requires,
- suggests: BTreeMap::new(),
+ suggests: indexmap::IndexMap::new(),
autoload,
dev_autoload: AutoloadRules::default(),
is_default_branch: false,
@@ -908,9 +862,9 @@ impl RootPackageData {
complete: complete_data,
minimum_stability,
prefer_stable,
- stability_flags: BTreeMap::new(),
+ stability_flags: indexmap::IndexMap::new(),
config,
- references: BTreeMap::new(),
+ references: indexmap::IndexMap::new(),
aliases: Vec::new(),
}
}
@@ -976,7 +930,7 @@ mod tests {
security_advisories: None,
}];
- let mut psr4 = BTreeMap::new();
+ let mut psr4 = indexmap::IndexMap::new();
psr4.insert("Acme\\Full\\".to_string(), "src/".to_string());
raw.autoload = Some(RawAutoload { psr4 });
diff --git a/crates/mozart-core/src/package/complete_package_interface.rs b/crates/mozart-core/src/package/complete_package_interface.rs
new file mode 100644
index 0000000..c321309
--- /dev/null
+++ b/crates/mozart-core/src/package/complete_package_interface.rs
@@ -0,0 +1,17 @@
+use crate::package::{Author, Funding, PackageInterface, Support};
+
+/// ref: \Composer\Package\CompletePackageInterface
+pub trait CompletePackageInterface: PackageInterface {
+ fn description(&self) -> Option<&str>;
+ fn homepage(&self) -> Option<&str>;
+ fn license(&self) -> &[String];
+ fn keywords(&self) -> &[String];
+ fn authors(&self) -> &[Author];
+ fn scripts(&self) -> &indexmap::IndexMap<String, Vec<String>>;
+ fn support(&self) -> &Support;
+ fn funding(&self) -> &[Funding];
+ fn repositories(&self) -> &[serde_json::Value];
+ fn abandoned(&self) -> Option<&str>;
+ fn archive_name(&self) -> Option<&str>;
+ fn archive_excludes(&self) -> &[String];
+}
diff --git a/crates/mozart-core/src/package/package_interface.rs b/crates/mozart-core/src/package/package_interface.rs
new file mode 100644
index 0000000..7006657
--- /dev/null
+++ b/crates/mozart-core/src/package/package_interface.rs
@@ -0,0 +1,33 @@
+use crate::package::{AutoloadRules, Link, Stability};
+
+/// ref: \Composer\Package\PackageInterface
+pub trait PackageInterface {
+ fn name(&self) -> &str;
+ fn pretty_name(&self) -> &str;
+ fn version(&self) -> &str;
+ fn pretty_version(&self) -> &str;
+ fn package_type(&self) -> &str;
+ fn target_dir(&self) -> Option<&str>;
+ fn source_type(&self) -> Option<&str>;
+ fn source_url(&self) -> Option<&str>;
+ fn source_reference(&self) -> Option<&str>;
+ fn dist_type(&self) -> Option<&str>;
+ fn dist_url(&self) -> Option<&str>;
+ fn dist_reference(&self) -> Option<&str>;
+ fn dist_sha1_checksum(&self) -> Option<&str>;
+ fn release_date(&self) -> Option<&str>;
+ fn extra(&self) -> &indexmap::IndexMap<String, serde_json::Value>;
+ fn binaries(&self) -> &[String];
+ fn is_dev(&self) -> bool;
+ fn stability(&self) -> Stability;
+ fn notification_url(&self) -> Option<&str>;
+ fn requires(&self) -> &indexmap::IndexMap<String, Link>;
+ fn conflicts(&self) -> &indexmap::IndexMap<String, Link>;
+ fn provides(&self) -> &indexmap::IndexMap<String, Link>;
+ fn replaces(&self) -> &indexmap::IndexMap<String, Link>;
+ fn dev_requires(&self) -> &indexmap::IndexMap<String, Link>;
+ fn suggests(&self) -> &indexmap::IndexMap<String, String>;
+ fn autoload(&self) -> &AutoloadRules;
+ fn dev_autoload(&self) -> &AutoloadRules;
+ fn is_default_branch(&self) -> bool;
+}
diff --git a/crates/mozart-core/src/repository/browse_repos.rs b/crates/mozart-core/src/repository/browse_repos.rs
index 83a40f1..a174637 100644
--- a/crates/mozart-core/src/repository/browse_repos.rs
+++ b/crates/mozart-core/src/repository/browse_repos.rs
@@ -8,8 +8,8 @@
//! `CompletePackageInterface` (`getSupport()['source']`,
//! `getSourceUrl()`, `getHomepage()`).
-use super::super::package::Package as _;
-use super::super::package::{CompletePackage as _, RootPackageData};
+use super::super::package::PackageInterface as _;
+use super::super::package::{CompletePackageInterface as _, RootPackageData};
use super::cache::Cache;
use super::installed::{InstalledPackageEntry, InstalledPackages};
use super::lockfile::LockedPackage;
@@ -167,7 +167,6 @@ impl BrowseRepos {
mod tests {
use super::*;
use crate::package::RawPackageData;
- use std::collections::BTreeMap;
fn locked(
name: &str,
@@ -185,11 +184,11 @@ mod tests {
reference: None,
}),
dist: None,
- require: BTreeMap::new(),
- require_dev: BTreeMap::new(),
- conflict: BTreeMap::new(),
- provide: BTreeMap::new(),
- replace: BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ require_dev: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
suggest: None,
package_type: None,
autoload: None,
@@ -202,7 +201,7 @@ mod tests {
support: support_source.map(|s| serde_json::json!({"source": s})),
funding: None,
time: None,
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
}
}
@@ -240,7 +239,7 @@ mod tests {
aliases: vec![],
homepage: Some("https://vendor.example.com".to_string()),
support: Some(serde_json::json!({"source": "https://github.com/vendor/pkg"})),
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
};
let view = CompletePackageView::from(&entry);
assert_eq!(
diff --git a/crates/mozart-core/src/repository/installed.rs b/crates/mozart-core/src/repository/installed.rs
index 422f79f..4bee0e5 100644
--- a/crates/mozart-core/src/repository/installed.rs
+++ b/crates/mozart-core/src/repository/installed.rs
@@ -1,7 +1,6 @@
use crate::installer::HasSuggests;
use crate::package::to_json_pretty;
use serde::{Deserialize, Serialize};
-use std::collections::BTreeMap;
use std::fs;
use std::path::Path;
@@ -56,7 +55,7 @@ pub struct InstalledPackageEntry {
pub support: Option<serde_json::Value>,
#[serde(flatten)]
- pub extra_fields: BTreeMap<String, serde_json::Value>,
+ pub extra_fields: indexmap::IndexMap<String, serde_json::Value>,
}
impl HasSuggests for InstalledPackageEntry {
@@ -215,7 +214,7 @@ mod tests {
aliases: vec![],
homepage: None,
support: None,
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
}
}
diff --git a/crates/mozart-core/src/repository/lockfile.rs b/crates/mozart-core/src/repository/lockfile.rs
index 146506d..cde7530 100644
--- a/crates/mozart-core/src/repository/lockfile.rs
+++ b/crates/mozart-core/src/repository/lockfile.rs
@@ -2,12 +2,12 @@ use super::packagist::{PackagistDist, PackagistSource, PackagistVersion};
use super::repository::RepositorySet;
use super::resolver::ResolvedPackage;
use crate::installer::HasSuggests;
-use crate::package::Package as _;
+use crate::package::PackageInterface as _;
use crate::package::{Link, RawPackageData, to_json_pretty};
use indexmap::IndexMap;
use indexmap::IndexSet;
use serde::{Deserialize, Serialize};
-use std::collections::{BTreeMap, VecDeque};
+use std::collections::VecDeque;
use std::fs;
use std::path::Path;
@@ -76,27 +76,27 @@ pub struct LockedPackage {
#[serde(skip_serializing_if = "Option::is_none")]
pub dist: Option<LockedDist>,
- #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
- pub require: BTreeMap<String, String>,
+ #[serde(default, skip_serializing_if = "indexmap::IndexMap::is_empty")]
+ pub require: indexmap::IndexMap<String, String>,
#[serde(
rename = "require-dev",
default,
- skip_serializing_if = "BTreeMap::is_empty"
+ skip_serializing_if = "indexmap::IndexMap::is_empty"
)]
- pub require_dev: BTreeMap<String, String>,
+ pub require_dev: indexmap::IndexMap<String, String>,
- #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
- pub conflict: BTreeMap<String, String>,
+ #[serde(default, skip_serializing_if = "indexmap::IndexMap::is_empty")]
+ pub conflict: indexmap::IndexMap<String, String>,
- #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
- pub provide: BTreeMap<String, String>,
+ #[serde(default, skip_serializing_if = "indexmap::IndexMap::is_empty")]
+ pub provide: indexmap::IndexMap<String, String>,
- #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
- pub replace: BTreeMap<String, String>,
+ #[serde(default, skip_serializing_if = "indexmap::IndexMap::is_empty")]
+ pub replace: indexmap::IndexMap<String, String>,
#[serde(skip_serializing_if = "Option::is_none")]
- pub suggest: Option<BTreeMap<String, String>>,
+ pub suggest: Option<indexmap::IndexMap<String, String>>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub package_type: Option<String>,
@@ -133,7 +133,7 @@ pub struct LockedPackage {
/// Catch-all for extra fields we don't explicitly model
#[serde(flatten)]
- pub extra_fields: BTreeMap<String, serde_json::Value>,
+ pub extra_fields: indexmap::IndexMap<String, serde_json::Value>,
}
impl HasSuggests for LockedPackage {
@@ -231,9 +231,9 @@ impl LockFile {
];
// Collect relevant keys into a BTreeMap (auto-sorted by key)
- let mut filtered: BTreeMap<&str, &serde_json::Value> = BTreeMap::new();
- for key in &relevant_keys {
- if let Some(v) = obj.get(*key) {
+ let mut filtered = std::collections::BTreeMap::new();
+ for key in relevant_keys {
+ if let Some(v) = obj.get(key) {
filtered.insert(key, v);
}
}
@@ -396,7 +396,7 @@ pub fn locked_package_branch_aliases(pkg: &LockedPackage) -> Vec<LockAlias> {
}
fn check_requirement_set(
- requires: &BTreeMap<String, Link>,
+ requires: &IndexMap<String, Link>,
description: &str,
pool: &[LockedSearchEntry],
messages: &mut Vec<String>,
@@ -626,10 +626,10 @@ fn packagist_dist_to_locked(pd: &PackagistDist) -> LockedDist {
/// `dev` after stripping the reference are left out (matching the
/// `'dev' === VersionParser::parseStability(...)` guard in PHP).
fn extract_root_references(
- require: &BTreeMap<String, String>,
- require_dev: &BTreeMap<String, String>,
-) -> BTreeMap<String, String> {
- let mut out = BTreeMap::new();
+ require: &IndexMap<String, String>,
+ require_dev: &IndexMap<String, String>,
+) -> indexmap::IndexMap<String, String> {
+ let mut out = indexmap::IndexMap::new();
for (name, raw_constraint) in require.iter().chain(require_dev.iter()) {
if let Some(reference) = parse_inline_reference(raw_constraint) {
out.insert(name.to_lowercase(), reference);
@@ -730,7 +730,7 @@ fn rewrite_known_dist_url_reference(url: &str, reference: &str) -> String {
/// Convert a `PackagistVersion` to a `LockedPackage`.
fn packagist_version_to_locked_package(name: &str, pv: &PackagistVersion) -> LockedPackage {
- let mut extra_fields: BTreeMap<String, serde_json::Value> = BTreeMap::new();
+ let mut extra_fields = indexmap::IndexMap::new();
if let Some(extra) = &pv.extra {
extra_fields.insert("extra".to_string(), extra.clone());
@@ -808,8 +808,8 @@ fn packagist_version_to_locked_package(name: &str, pv: &PackagistVersion) -> Loc
/// declares `provide: { provided/pkg: 1.0.0 }`.
fn classify_dev_packages(
resolved: &[ResolvedPackage],
- require: &BTreeMap<String, String>,
- _require_dev: &BTreeMap<String, String>,
+ require: &IndexMap<String, String>,
+ _require_dev: &IndexMap<String, String>,
requires_by_name: &IndexMap<String, Vec<String>>,
providers_by_name: &IndexMap<String, Vec<String>>,
) -> IndexSet<String> {
@@ -874,7 +874,7 @@ fn is_platform_name(name: &str) -> bool {
///
/// Filters the map to include only platform package keys (`php`, `ext-*`, `lib-*`, etc.)
/// and returns them as a JSON object.
-fn extract_platform_requirements(requirements: &BTreeMap<String, String>) -> serde_json::Value {
+fn extract_platform_requirements(requirements: &IndexMap<String, String>) -> serde_json::Value {
let map: serde_json::Map<String, serde_json::Value> = requirements
.iter()
.filter(|(k, _)| is_platform_name(k))
@@ -920,12 +920,12 @@ pub async fn generate_lock_file(request: &LockFileGenerationRequest) -> anyhow::
// resolver picked a new commit at the same version label) still get
// their ref refreshed.
struct PreservedRelationships {
- require: BTreeMap<String, String>,
- require_dev: BTreeMap<String, String>,
- conflict: BTreeMap<String, String>,
- provide: BTreeMap<String, String>,
- replace: BTreeMap<String, String>,
- suggest: Option<BTreeMap<String, String>>,
+ require: indexmap::IndexMap<String, String>,
+ require_dev: indexmap::IndexMap<String, String>,
+ conflict: indexmap::IndexMap<String, String>,
+ provide: indexmap::IndexMap<String, String>,
+ replace: indexmap::IndexMap<String, String>,
+ suggest: Option<indexmap::IndexMap<String, String>>,
}
let mut preserved_rel: IndexMap<String, PreservedRelationships> = IndexMap::new();
if let Some(prev) = &request.previous_lock {
@@ -1229,11 +1229,11 @@ mod tests {
reference: Some("abc123".to_string()),
shasum: Some("".to_string()),
}),
- require: BTreeMap::new(),
- require_dev: BTreeMap::new(),
- conflict: BTreeMap::new(),
- provide: BTreeMap::new(),
- replace: BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ require_dev: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
suggest: None,
package_type: Some("library".to_string()),
autoload: None,
@@ -1246,7 +1246,7 @@ mod tests {
support: None,
funding: None,
time: None,
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
});
lock.write_to_file(&path).unwrap();
@@ -1320,15 +1320,15 @@ mod tests {
fn make_packagist_version(
version: &str,
version_normalized: &str,
- require: BTreeMap<String, String>,
+ require: indexmap::IndexMap<String, String>,
) -> PackagistVersion {
PackagistVersion {
version: version.to_string(),
version_normalized: version_normalized.to_string(),
require,
- replace: BTreeMap::new(),
- provide: BTreeMap::new(),
- conflict: BTreeMap::new(),
+ replace: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
dist: Some(super::super::packagist::PackagistDist {
dist_type: "zip".to_string(),
url: format!("https://example.com/{version}.zip"),
@@ -1340,7 +1340,7 @@ mod tests {
url: "https://github.com/example/pkg.git".to_string(),
reference: Some("deadbeef".to_string()),
}),
- require_dev: BTreeMap::new(),
+ require_dev: indexmap::IndexMap::new(),
suggest: None,
package_type: Some("library".to_string()),
autoload: Some(serde_json::json!({"psr-4": {"Example\\": "src/"}})),
@@ -1366,7 +1366,7 @@ mod tests {
#[test]
fn test_packagist_version_to_locked_package() {
- let pv = make_packagist_version("1.2.3", "1.2.3.0", BTreeMap::new());
+ let pv = make_packagist_version("1.2.3", "1.2.3.0", indexmap::IndexMap::new());
let locked = packagist_version_to_locked_package("example/pkg", &pv);
assert_eq!(locked.name, "example/pkg");
@@ -1414,13 +1414,13 @@ mod tests {
let pv = PackagistVersion {
version: "1.0.0".to_string(),
version_normalized: "1.0.0.0".to_string(),
- require: BTreeMap::new(),
- replace: BTreeMap::new(),
- provide: BTreeMap::new(),
- conflict: BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
dist: None,
source: None,
- require_dev: BTreeMap::new(),
+ require_dev: indexmap::IndexMap::new(),
suggest: None,
package_type: None,
autoload: None,
@@ -1484,16 +1484,16 @@ mod tests {
},
];
- let mut require = BTreeMap::new();
+ let mut require = indexmap::IndexMap::new();
require.insert("vendor/a".to_string(), "^1.0".to_string());
- let mut require_dev = BTreeMap::new();
+ let mut require_dev = indexmap::IndexMap::new();
require_dev.insert("vendor/b".to_string(), "^1.0".to_string());
let mut metadata: IndexMap<String, PackagistVersion> = IndexMap::new();
// A requires C
- let mut a_require = BTreeMap::new();
+ let mut a_require = indexmap::IndexMap::new();
a_require.insert("vendor/c".to_string(), "^1.0".to_string());
metadata.insert(
"vendor/a".to_string(),
@@ -1501,7 +1501,7 @@ mod tests {
);
// B requires D
- let mut b_require = BTreeMap::new();
+ let mut b_require = indexmap::IndexMap::new();
b_require.insert("vendor/d".to_string(), "^1.0".to_string());
metadata.insert(
"vendor/b".to_string(),
@@ -1511,11 +1511,11 @@ mod tests {
// C and D have no deps
metadata.insert(
"vendor/c".to_string(),
- make_packagist_version("1.0.0", "1.0.0.0", BTreeMap::new()),
+ make_packagist_version("1.0.0", "1.0.0.0", indexmap::IndexMap::new()),
);
metadata.insert(
"vendor/d".to_string(),
- make_packagist_version("1.0.0", "1.0.0.0", BTreeMap::new()),
+ make_packagist_version("1.0.0", "1.0.0.0", indexmap::IndexMap::new()),
);
let requires_by_name: IndexMap<String, Vec<String>> = metadata
@@ -1577,16 +1577,16 @@ mod tests {
},
];
- let mut require = BTreeMap::new();
+ let mut require = indexmap::IndexMap::new();
require.insert("vendor/a".to_string(), "^1.0".to_string());
- let mut require_dev = BTreeMap::new();
+ let mut require_dev = indexmap::IndexMap::new();
require_dev.insert("vendor/b".to_string(), "^1.0".to_string());
let mut metadata: IndexMap<String, PackagistVersion> = IndexMap::new();
// A requires C
- let mut a_require = BTreeMap::new();
+ let mut a_require = indexmap::IndexMap::new();
a_require.insert("vendor/c".to_string(), "^1.0".to_string());
metadata.insert(
"vendor/a".to_string(),
@@ -1594,7 +1594,7 @@ mod tests {
);
// B also requires C
- let mut b_require = BTreeMap::new();
+ let mut b_require = indexmap::IndexMap::new();
b_require.insert("vendor/c".to_string(), "^1.0".to_string());
metadata.insert(
"vendor/b".to_string(),
@@ -1604,7 +1604,7 @@ mod tests {
// C has no deps
metadata.insert(
"vendor/c".to_string(),
- make_packagist_version("1.0.0", "1.0.0.0", BTreeMap::new()),
+ make_packagist_version("1.0.0", "1.0.0.0", indexmap::IndexMap::new()),
);
let requires_by_name: IndexMap<String, Vec<String>> = metadata
@@ -1636,7 +1636,7 @@ mod tests {
#[test]
fn test_extract_platform_requirements() {
- let mut requirements = BTreeMap::new();
+ let mut requirements = indexmap::IndexMap::new();
requirements.insert("php".to_string(), ">=8.1".to_string());
requirements.insert("ext-json".to_string(), "*".to_string());
requirements.insert("ext-mbstring".to_string(), "*".to_string());
@@ -1669,7 +1669,7 @@ mod tests {
#[test]
fn test_extract_platform_requirements_empty() {
- let requirements = BTreeMap::new();
+ let requirements = indexmap::IndexMap::new();
let platform = extract_platform_requirements(&requirements);
assert_eq!(platform, serde_json::json!({}));
}
@@ -1729,11 +1729,11 @@ mod tests {
version_normalized: None,
source: None,
dist: None,
- require: BTreeMap::new(),
- require_dev: BTreeMap::new(),
- conflict: BTreeMap::new(),
- provide: BTreeMap::new(),
- replace: BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ require_dev: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
suggest: None,
package_type: None,
autoload: None,
@@ -1746,7 +1746,7 @@ mod tests {
support: None,
funding: None,
time: None,
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
},
LockedPackage {
name: "vendor/alpha".to_string(),
@@ -1754,11 +1754,11 @@ mod tests {
version_normalized: None,
source: None,
dist: None,
- require: BTreeMap::new(),
- require_dev: BTreeMap::new(),
- conflict: BTreeMap::new(),
- provide: BTreeMap::new(),
- replace: BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ require_dev: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
suggest: None,
package_type: None,
autoload: None,
@@ -1771,7 +1771,7 @@ mod tests {
support: None,
funding: None,
time: None,
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
},
];
@@ -1892,11 +1892,11 @@ mod tests {
version_normalized: None,
source: None,
dist: None,
- require: BTreeMap::new(),
- require_dev: BTreeMap::new(),
- conflict: BTreeMap::new(),
- provide: BTreeMap::new(),
- replace: BTreeMap::new(),
+ require: indexmap::IndexMap::new(),
+ require_dev: indexmap::IndexMap::new(),
+ conflict: indexmap::IndexMap::new(),
+ provide: indexmap::IndexMap::new(),
+ replace: indexmap::IndexMap::new(),
suggest: None,
package_type: Some("library".to_string()),
autoload: None,
@@ -1909,7 +1909,7 @@ mod tests {
support: None,
funding: None,
time: None,
- extra_fields: BTreeMap::new(),
+ extra_fields: indexmap::IndexMap::new(),
}
}
diff --git a/crates/mozart-core/src/repository/packagist.rs b/crates/mozart-core/src/repository/packagist.rs
index 199ff51..91b47df 100644
--- a/crates/mozart-core/src/repository/packagist.rs
+++ b/crates/mozart-core/src/repository/packagist.rs
@@ -55,13 +55,13 @@ pub struct PackagistVersion {
pub version: String,
pub version_normalized: String,
#[serde(default, deserialize_with = "deserialize_unset_as_default")]
- pub require: BTreeMap<String, String>,
+ pub require: indexmap::IndexMap<String, String>,
#[serde(default, deserialize_with = "deserialize_unset_as_default")]
- pub replace: BTreeMap<String, String>,
+ pub replace: indexmap::IndexMap<String, String>,
#[serde(default, deserialize_with = "deserialize_unset_as_default")]
- pub provide: BTreeMap<String, String>,
+ pub provide: indexmap::IndexMap<String, String>,
#[serde(default, deserialize_with = "deserialize_unset_as_default")]
- pub conflict: BTreeMap<String, String>,
+ pub conflict: indexmap::IndexMap<String, String>,
#[serde(default, deserialize_with = "deserialize_unset_as_none")]
pub dist: Option<PackagistDist>,
#[serde(default, deserialize_with = "deserialize_unset_as_none")]
@@ -72,10 +72,10 @@ pub struct PackagistVersion {
default,
deserialize_with = "deserialize_unset_as_default"
)]
- pub require_dev: BTreeMap<String, String>,
+ pub require_dev: indexmap::IndexMap<String, String>,
#[serde(default, deserialize_with = "deserialize_unset_as_none")]
- pub suggest: Option<BTreeMap<String, String>>,
+ pub suggest: Option<indexmap::IndexMap<String, String>>,
#[serde(
rename = "type",
@@ -160,17 +160,17 @@ impl PackagistVersion {
///
/// Returns a map from branch name (e.g. `"dev-master"`) to alias target
/// (e.g. `"2.x-dev"`). Returns an empty map when no aliases are declared.
- pub fn branch_aliases(&self) -> BTreeMap<String, String> {
+ pub fn branch_aliases(&self) -> indexmap::IndexMap<String, String> {
let Some(extra) = &self.extra else {
- return BTreeMap::new();
+ return indexmap::IndexMap::new();
};
let Some(branch_alias) = extra.get("branch-alias") else {
- return BTreeMap::new();
+ return indexmap::IndexMap::new();
};
let Some(map) = branch_alias.as_object() else {
- return BTreeMap::new();
+ return indexmap::IndexMap::new();
};
map.iter()
diff --git a/crates/mozart-core/src/repository/vcs_bridge.rs b/crates/mozart-core/src/repository/vcs_bridge.rs
index 18a8420..79c0c5b 100644
--- a/crates/mozart-core/src/repository/vcs_bridge.rs
+++ b/crates/mozart-core/src/repository/vcs_bridge.rs
@@ -10,7 +10,6 @@ use crate::repository::resolver::{parse_normalized, version_stability};
use crate::repository::vcs::DriverConfig;
use crate::vcs::repository::{VcsPackageVersion, VcsRepository};
use indexmap::IndexMap;
-use std::collections::BTreeMap;
/// Scan all VCS-type repositories and collect package versions.
///
@@ -191,7 +190,7 @@ pub fn vcs_to_packagist_version(vpkg: &VcsPackageVersion) -> PackagistVersion {
}
/// Extract a dependency map from composer.json JSON.
-fn extract_dep_map(json: &serde_json::Value, key: &str) -> BTreeMap<String, String> {
+fn extract_dep_map(json: &serde_json::Value, key: &str) -> indexmap::IndexMap<String, String> {
json.get(key)
.and_then(|v| v.as_object())
.map(|obj| {
diff --git a/crates/mozart-core/src/repository_utils.rs b/crates/mozart-core/src/repository_utils.rs
index b16a0d6..7a797c4 100644
--- a/crates/mozart-core/src/repository_utils.rs
+++ b/crates/mozart-core/src/repository_utils.rs
@@ -19,7 +19,7 @@ use std::collections::BTreeSet;
/// `package_name` only in that case.
pub trait Required {
fn package_name(&self) -> &str;
- fn requires(&self) -> &std::collections::BTreeMap<String, String>;
+ fn requires(&self) -> &indexmap::IndexMap<String, String>;
fn package_names(&self) -> Option<Vec<&str>> {
None
}
@@ -38,8 +38,8 @@ pub trait Required {
/// discovered, matching PHP's `$bucket[] = $candidate;` push pattern.
pub fn filter_required_packages<P, V>(
packages: &[P],
- requirer_requires: &std::collections::BTreeMap<String, V>,
- requirer_dev_requires: Option<&std::collections::BTreeMap<String, V>>,
+ requirer_requires: &indexmap::IndexMap<String, V>,
+ requirer_dev_requires: Option<&indexmap::IndexMap<String, V>>,
) -> Vec<usize>
where
P: Required,
@@ -78,24 +78,23 @@ where
#[cfg(test)]
mod tests {
use super::*;
- use std::collections::BTreeMap;
struct Pkg {
name: String,
- requires: BTreeMap<String, String>,
+ requires: indexmap::IndexMap<String, String>,
}
impl Required for Pkg {
fn package_name(&self) -> &str {
&self.name
}
- fn requires(&self) -> &BTreeMap<String, String> {
+ fn requires(&self) -> &indexmap::IndexMap<String, String> {
&self.requires
}
}
fn pkg(name: &str, requires: &[&str]) -> Pkg {
- let mut r = BTreeMap::new();
+ let mut r = indexmap::IndexMap::new();
for n in requires {
r.insert(n.to_string(), "*".to_string());
}
@@ -105,8 +104,8 @@ mod tests {
}
}
- fn root_requires(names: &[&str]) -> BTreeMap<String, String> {
- let mut m = BTreeMap::new();
+ fn root_requires(names: &[&str]) -> indexmap::IndexMap<String, String> {
+ let mut m = indexmap::IndexMap::new();
for n in names {
m.insert(n.to_string(), "*".to_string());
}
@@ -167,7 +166,7 @@ mod tests {
#[test]
fn empty_requires_yields_nothing() {
let packages = vec![pkg("a/a", &[]), pkg("b/b", &[])];
- let root: BTreeMap<String, String> = BTreeMap::new();
+ let root: indexmap::IndexMap<_, ()> = indexmap::IndexMap::new();
let kept = filter_required_packages(&packages, &root, None);
assert!(kept.is_empty());
}