aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/package
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/package')
-rw-r--r--crates/shirabe/src/package/alias_package.rs57
-rw-r--r--crates/shirabe/src/package/base_package.rs2
-rw-r--r--crates/shirabe/src/package/complete_alias_package.rs114
-rw-r--r--crates/shirabe/src/package/handle.rs1440
-rw-r--r--crates/shirabe/src/package/loader/array_loader.rs23
-rw-r--r--crates/shirabe/src/package/loader/json_loader.rs4
-rw-r--r--crates/shirabe/src/package/loader/loader_interface.rs4
-rw-r--r--crates/shirabe/src/package/loader/root_package_loader.rs11
-rw-r--r--crates/shirabe/src/package/loader/validating_array_loader.rs2
-rw-r--r--crates/shirabe/src/package/locker.rs43
-rw-r--r--crates/shirabe/src/package/mod.rs2
-rw-r--r--crates/shirabe/src/package/package.rs4
-rw-r--r--crates/shirabe/src/package/package_interface.rs8
-rw-r--r--crates/shirabe/src/package/root_alias_package.rs285
-rw-r--r--crates/shirabe/src/package/root_package.rs4
-rw-r--r--crates/shirabe/src/package/root_package_interface.rs8
-rw-r--r--crates/shirabe/src/package/version/version_selector.rs34
17 files changed, 1676 insertions, 369 deletions
diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs
index e9b5dbf..5558337 100644
--- a/crates/shirabe/src/package/alias_package.rs
+++ b/crates/shirabe/src/package/alias_package.rs
@@ -8,6 +8,7 @@ use shirabe_semver::constraint::SimpleConstraint;
use crate::package::BasePackage;
use crate::package::Link;
+use crate::package::PackageHandle;
use crate::package::PackageInterface;
use crate::package::version::VersionParser;
use crate::repository::RepositoryInterface;
@@ -34,7 +35,7 @@ pub struct AliasPackage {
pub(crate) has_self_version_requires: bool,
/// @var BasePackage
- pub(crate) alias_of: Box<dyn BasePackage>,
+ pub(crate) alias_of: PackageHandle,
/// @var Link[]
pub(crate) requires: IndexMap<String, Link>,
/// @var Link[]
@@ -53,8 +54,8 @@ impl AliasPackage {
/// @param BasePackage $aliasOf The package this package is an alias of
/// @param string $version The version the alias must report
/// @param string $prettyVersion The alias's non-normalized version
- pub fn new(alias_of: Box<dyn BasePackage>, version: String, pretty_version: String) -> Self {
- let alias_name = alias_of.get_name().to_string();
+ pub fn new(alias_of: PackageHandle, version: String, pretty_version: String) -> Self {
+ let alias_name = alias_of.get_name();
let stability = VersionParser::parse_stability(&version).to_string();
let dev = stability == "dev";
@@ -130,12 +131,8 @@ impl AliasPackage {
this
}
- pub fn get_alias_of(&self) -> &dyn BasePackage {
- self.alias_of.as_ref()
- }
-
- pub fn get_alias_of_mut(&mut self) -> &mut dyn BasePackage {
- &mut *self.alias_of
+ pub fn get_alias_of(&self) -> PackageHandle {
+ self.alias_of.clone()
}
/// Stores whether this is an alias created by an aliasing in the requirements of the root package or not
@@ -244,11 +241,13 @@ impl PackageInterface for AliasPackage {
}
fn get_name(&self) -> &str {
- self.alias_of.get_name()
+ // PHP delegates to aliasOf; the local name mirrors aliasOf->getName(),
+ // so it is returned here to avoid borrowing across the shared handle.
+ &self.name
}
fn get_pretty_name(&self) -> &str {
- self.alias_of.get_pretty_name()
+ &self.pretty_name
}
fn get_names(&self, provides: bool) -> Vec<String> {
@@ -306,11 +305,14 @@ impl PackageInterface for AliasPackage {
}
fn get_type(&self) -> &str {
- self.alias_of.get_type()
+ // Delegates to the shared `aliasOf` handle, whose getters yield owned
+ // `String`s; a borrow cannot escape the `RefCell`. Use the handle API
+ // (`AliasPackageHandle::get_alias_of().get_type()`) instead.
+ todo!("AliasPackage::get_type cannot return &str across the aliasOf handle")
}
fn get_target_dir(&self) -> Option<&str> {
- self.alias_of.get_target_dir()
+ todo!("AliasPackage::get_target_dir cannot return &str across the aliasOf handle")
}
fn get_extra(&self) -> IndexMap<String, PhpMixed> {
@@ -322,15 +324,15 @@ impl PackageInterface for AliasPackage {
}
fn get_installation_source(&self) -> Option<&str> {
- self.alias_of.get_installation_source()
+ todo!("AliasPackage::get_installation_source cannot return &str across the aliasOf handle")
}
fn get_source_type(&self) -> Option<&str> {
- self.alias_of.get_source_type()
+ todo!("AliasPackage::get_source_type cannot return &str across the aliasOf handle")
}
fn get_source_url(&self) -> Option<&str> {
- self.alias_of.get_source_url()
+ todo!("AliasPackage::get_source_url cannot return &str across the aliasOf handle")
}
fn get_source_urls(&self) -> Vec<String> {
@@ -338,7 +340,7 @@ impl PackageInterface for AliasPackage {
}
fn get_source_reference(&self) -> Option<&str> {
- self.alias_of.get_source_reference()
+ todo!("AliasPackage::get_source_reference cannot return &str across the aliasOf handle")
}
fn set_source_reference(&mut self, reference: Option<String>) {
@@ -354,11 +356,11 @@ impl PackageInterface for AliasPackage {
}
fn get_dist_type(&self) -> Option<&str> {
- self.alias_of.get_dist_type()
+ todo!("AliasPackage::get_dist_type cannot return &str across the aliasOf handle")
}
fn get_dist_url(&self) -> Option<&str> {
- self.alias_of.get_dist_url()
+ todo!("AliasPackage::get_dist_url cannot return &str across the aliasOf handle")
}
fn get_dist_urls(&self) -> Vec<String> {
@@ -366,7 +368,7 @@ impl PackageInterface for AliasPackage {
}
fn get_dist_reference(&self) -> Option<&str> {
- self.alias_of.get_dist_reference()
+ todo!("AliasPackage::get_dist_reference cannot return &str across the aliasOf handle")
}
fn set_dist_reference(&mut self, reference: Option<String>) {
@@ -374,7 +376,7 @@ impl PackageInterface for AliasPackage {
}
fn get_dist_sha1_checksum(&self) -> Option<&str> {
- self.alias_of.get_dist_sha1_checksum()
+ todo!("AliasPackage::get_dist_sha1_checksum cannot return &str across the aliasOf handle")
}
fn set_transport_options(&mut self, options: IndexMap<String, PhpMixed>) {
@@ -422,7 +424,7 @@ impl PackageInterface for AliasPackage {
}
fn get_notification_url(&self) -> Option<&str> {
- self.alias_of.get_notification_url()
+ todo!("AliasPackage::get_notification_url cannot return &str across the aliasOf handle")
}
fn is_default_branch(&self) -> bool {
@@ -442,9 +444,8 @@ impl PackageInterface for AliasPackage {
}
fn get_full_pretty_version(&self, truncate: bool, display_mode: i64) -> String {
- // TODO(phase-b): BasePackage.get_full_pretty_version returns Result; bridge here
- BasePackage::get_full_pretty_version(self.alias_of.as_ref(), truncate, display_mode)
- .unwrap_or_default()
+ self.alias_of
+ .get_full_pretty_version(truncate, display_mode)
}
fn get_unique_name(&self) -> String {
@@ -460,7 +461,7 @@ impl PackageInterface for AliasPackage {
}
fn get_repository(&self) -> Option<&dyn RepositoryInterface> {
- self.alias_of.get_repository()
+ todo!("AliasPackage::get_repository cannot return a borrow across the aliasOf handle")
}
}
@@ -500,8 +501,4 @@ impl BasePackage for AliasPackage {
fn take_repository(&mut self) -> Option<Box<dyn RepositoryInterface>> {
todo!()
}
-
- fn clone_box(&self) -> Box<dyn BasePackage> {
- todo!()
- }
}
diff --git a/crates/shirabe/src/package/base_package.rs b/crates/shirabe/src/package/base_package.rs
index 75bd22f..64a5919 100644
--- a/crates/shirabe/src/package/base_package.rs
+++ b/crates/shirabe/src/package/base_package.rs
@@ -89,8 +89,6 @@ pub trait BasePackage: PackageInterface + std::fmt::Display {
// TODO(phase-b): wire up a back-reference to the containing repository when needed.
}
- fn clone_box(&self) -> Box<dyn BasePackage>;
-
// as_alias_package / as_complete_package_interface inherited from PackageInterface.
fn as_alias_package_mut(&mut self) -> Option<&mut crate::package::AliasPackage> {
diff --git a/crates/shirabe/src/package/complete_alias_package.rs b/crates/shirabe/src/package/complete_alias_package.rs
index 530bd03..6a23bee 100644
--- a/crates/shirabe/src/package/complete_alias_package.rs
+++ b/crates/shirabe/src/package/complete_alias_package.rs
@@ -1,136 +1,156 @@
//! ref: composer/src/Composer/Package/CompleteAliasPackage.php
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
+
use crate::package::AliasPackage;
-use crate::package::CompletePackage;
+use crate::package::CompletePackageHandle;
use crate::package::CompletePackageInterface;
+use crate::package::PackageHandle;
+use crate::package::handle::delegate_package_interface_to_inner;
#[derive(Debug)]
pub struct CompleteAliasPackage {
inner: AliasPackage,
// overrides AliasPackage::alias_of with the more specific CompletePackage type
- pub(crate) alias_of: CompletePackage,
+ pub(crate) alias_of: CompletePackageHandle,
}
impl CompleteAliasPackage {
- pub fn new(alias_of: CompletePackage, version: String, pretty_version: String) -> Self {
- // TODO(phase-b): alias_of is a PHP class (shared semantics); cloning is wrong.
- // Use a dummy BasePackage placeholder until the field is migrated to Rc<CompletePackage>.
+ pub fn new(alias_of: CompletePackageHandle, version: String, pretty_version: String) -> Self {
let inner = AliasPackage::new(
- todo!("share CompletePackage via Rc"),
+ PackageHandle::from(alias_of.clone()),
version,
pretty_version,
);
Self { inner, alias_of }
}
- pub fn get_alias_of(&self) -> &CompletePackage {
- &self.alias_of
+ pub fn get_alias_of(&self) -> CompletePackageHandle {
+ self.alias_of.clone()
+ }
+
+ pub fn set_root_package_alias(&mut self, value: bool) {
+ self.inner.set_root_package_alias(value);
+ }
+
+ pub fn is_root_package_alias(&self) -> bool {
+ self.inner.is_root_package_alias()
+ }
+
+ pub fn has_self_version_requires(&self) -> bool {
+ self.inner.has_self_version_requires()
+ }
+}
+
+delegate_package_interface_to_inner!(CompleteAliasPackage, inner);
+
+impl std::fmt::Display for CompleteAliasPackage {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(&self.inner, f)
}
+}
- pub fn get_scripts(&self) -> indexmap::IndexMap<String, Vec<String>> {
+impl CompletePackageInterface for CompleteAliasPackage {
+ fn get_scripts(&self) -> IndexMap<String, Vec<String>> {
self.alias_of.get_scripts()
}
- pub fn set_scripts(&mut self, scripts: indexmap::IndexMap<String, Vec<String>>) {
+ fn set_scripts(&mut self, scripts: IndexMap<String, Vec<String>>) {
self.alias_of.set_scripts(scripts);
}
- pub fn get_repositories(&self) -> Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>> {
+ fn get_repositories(&self) -> Vec<IndexMap<String, PhpMixed>> {
self.alias_of.get_repositories()
}
- pub fn set_repositories(
- &mut self,
- repositories: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>,
- ) {
+ fn set_repositories(&mut self, repositories: Vec<IndexMap<String, PhpMixed>>) {
self.alias_of.set_repositories(repositories);
}
- pub fn get_license(&self) -> Vec<String> {
+ fn get_license(&self) -> Vec<String> {
self.alias_of.get_license()
}
- pub fn set_license(&mut self, license: Vec<String>) {
+ fn set_license(&mut self, license: Vec<String>) {
self.alias_of.set_license(license);
}
- pub fn get_keywords(&self) -> Vec<String> {
+ fn get_keywords(&self) -> Vec<String> {
self.alias_of.get_keywords()
}
- pub fn set_keywords(&mut self, keywords: Vec<String>) {
+ fn set_keywords(&mut self, keywords: Vec<String>) {
self.alias_of.set_keywords(keywords);
}
- pub fn get_description(&self) -> Option<&str> {
- self.alias_of.get_description()
+ fn get_description(&self) -> Option<&str> {
+ todo!("CompleteAliasPackage::get_description cannot return &str across the aliasOf handle")
}
- pub fn set_description(&mut self, description: Option<String>) {
- self.alias_of
- .set_description(description.unwrap_or_default());
+ fn set_description(&mut self, description: String) {
+ self.alias_of.set_description(description);
}
- pub fn get_homepage(&self) -> Option<&str> {
- self.alias_of.get_homepage()
+ fn get_homepage(&self) -> Option<&str> {
+ todo!("CompleteAliasPackage::get_homepage cannot return &str across the aliasOf handle")
}
- pub fn set_homepage(&mut self, homepage: Option<String>) {
- self.alias_of.set_homepage(homepage.unwrap_or_default());
+ fn set_homepage(&mut self, homepage: String) {
+ self.alias_of.set_homepage(homepage);
}
- pub fn get_authors(&self) -> Vec<indexmap::IndexMap<String, String>> {
+ fn get_authors(&self) -> Vec<IndexMap<String, String>> {
self.alias_of.get_authors()
}
- pub fn set_authors(&mut self, authors: Vec<indexmap::IndexMap<String, String>>) {
+ fn set_authors(&mut self, authors: Vec<IndexMap<String, String>>) {
self.alias_of.set_authors(authors);
}
- pub fn get_support(&self) -> indexmap::IndexMap<String, String> {
+ fn get_support(&self) -> IndexMap<String, String> {
self.alias_of.get_support()
}
- pub fn set_support(&mut self, support: indexmap::IndexMap<String, String>) {
+ fn set_support(&mut self, support: IndexMap<String, String>) {
self.alias_of.set_support(support);
}
- pub fn get_funding(&self) -> Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>> {
+ fn get_funding(&self) -> Vec<IndexMap<String, PhpMixed>> {
self.alias_of.get_funding()
}
- pub fn set_funding(
- &mut self,
- funding: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>,
- ) {
+ fn set_funding(&mut self, funding: Vec<IndexMap<String, PhpMixed>>) {
self.alias_of.set_funding(funding);
}
- pub fn is_abandoned(&self) -> bool {
+ fn is_abandoned(&self) -> bool {
self.alias_of.is_abandoned()
}
- pub fn get_replacement_package(&self) -> Option<&str> {
- self.alias_of.get_replacement_package()
+ fn get_replacement_package(&self) -> Option<&str> {
+ todo!(
+ "CompleteAliasPackage::get_replacement_package cannot return &str across the aliasOf handle"
+ )
}
- pub fn set_abandoned(&mut self, abandoned: shirabe_php_shim::PhpMixed) {
+ fn set_abandoned(&mut self, abandoned: PhpMixed) {
self.alias_of.set_abandoned(abandoned);
}
- pub fn get_archive_name(&self) -> Option<&str> {
- self.alias_of.get_archive_name()
+ fn get_archive_name(&self) -> Option<&str> {
+ todo!("CompleteAliasPackage::get_archive_name cannot return &str across the aliasOf handle")
}
- pub fn set_archive_name(&mut self, name: Option<String>) {
- self.alias_of.set_archive_name(name.unwrap_or_default());
+ fn set_archive_name(&mut self, name: String) {
+ self.alias_of.set_archive_name(name);
}
- pub fn get_archive_excludes(&self) -> Vec<String> {
+ fn get_archive_excludes(&self) -> Vec<String> {
self.alias_of.get_archive_excludes()
}
- pub fn set_archive_excludes(&mut self, excludes: Vec<String>) {
+ fn set_archive_excludes(&mut self, excludes: Vec<String>) {
self.alias_of.set_archive_excludes(excludes);
}
}
diff --git a/crates/shirabe/src/package/handle.rs b/crates/shirabe/src/package/handle.rs
new file mode 100644
index 0000000..e1f0570
--- /dev/null
+++ b/crates/shirabe/src/package/handle.rs
@@ -0,0 +1,1440 @@
+//! Shared handles over the package types.
+//!
+//! No weak handles are provided: an alias package never aliases another alias package, so the
+//! `alias_of` references are acyclic.
+
+use std::cell::RefCell;
+use std::rc::Rc;
+
+use crate::package::{
+ AliasPackage, CompleteAliasPackage, CompletePackage, CompletePackageInterface, Package,
+ PackageInterface, RootAliasPackage, RootPackage, RootPackageInterface,
+};
+
+/// Any package type.
+#[derive(Debug)]
+pub enum AnyPackage {
+ Package(Package),
+ CompletePackage(CompletePackage),
+ RootPackage(RootPackage),
+ AliasPackage(AliasPackage),
+ CompleteAliasPackage(CompleteAliasPackage),
+ RootAliasPackage(RootAliasPackage),
+}
+
+impl AnyPackage {
+ pub fn as_package_interface(&self) -> &dyn PackageInterface {
+ match self {
+ Self::Package(p) => p,
+ Self::CompletePackage(p) => p,
+ Self::RootPackage(p) => p,
+ Self::AliasPackage(p) => p,
+ Self::CompleteAliasPackage(p) => p,
+ Self::RootAliasPackage(p) => p,
+ }
+ }
+
+ pub fn as_package_interface_mut(&mut self) -> &mut dyn PackageInterface {
+ match self {
+ Self::Package(p) => p,
+ Self::CompletePackage(p) => p,
+ Self::RootPackage(p) => p,
+ Self::AliasPackage(p) => p,
+ Self::CompleteAliasPackage(p) => p,
+ Self::RootAliasPackage(p) => p,
+ }
+ }
+
+ pub fn as_complete_package_interface(&self) -> Option<&dyn CompletePackageInterface> {
+ match self {
+ Self::CompletePackage(p) => Some(p),
+ Self::RootPackage(p) => Some(p),
+ Self::CompleteAliasPackage(p) => Some(p),
+ Self::RootAliasPackage(p) => Some(p),
+ _ => None,
+ }
+ }
+
+ pub fn as_complete_package_interface_mut(
+ &mut self,
+ ) -> Option<&mut dyn CompletePackageInterface> {
+ match self {
+ Self::CompletePackage(p) => Some(p),
+ Self::RootPackage(p) => Some(p),
+ Self::CompleteAliasPackage(p) => Some(p),
+ Self::RootAliasPackage(p) => Some(p),
+ _ => None,
+ }
+ }
+
+ pub fn as_root_package_interface(&self) -> Option<&dyn RootPackageInterface> {
+ match self {
+ Self::RootPackage(p) => Some(p),
+ Self::RootAliasPackage(p) => Some(p),
+ _ => None,
+ }
+ }
+
+ pub fn as_root_package_interface_mut(&mut self) -> Option<&mut dyn RootPackageInterface> {
+ match self {
+ Self::RootPackage(p) => Some(p),
+ Self::RootAliasPackage(p) => Some(p),
+ _ => None,
+ }
+ }
+
+ /// PHP `$p instanceof AliasPackage`.
+ pub fn is_alias(&self) -> bool {
+ matches!(
+ self,
+ Self::AliasPackage(_) | Self::CompleteAliasPackage(_) | Self::RootAliasPackage(_)
+ )
+ }
+
+ /// PHP `$p instanceof CompletePackageInterface`.
+ pub fn is_complete(&self) -> bool {
+ matches!(
+ self,
+ Self::CompletePackage(_)
+ | Self::RootPackage(_)
+ | Self::CompleteAliasPackage(_)
+ | Self::RootAliasPackage(_)
+ )
+ }
+
+ /// PHP `$p instanceof RootPackageInterface`.
+ pub fn is_root(&self) -> bool {
+ matches!(self, Self::RootPackage(_) | Self::RootAliasPackage(_))
+ }
+
+ /// A real (non-alias) package: `Package` / `CompletePackage` / `RootPackage`.
+ pub fn is_real(&self) -> bool {
+ matches!(
+ self,
+ Self::Package(_) | Self::CompletePackage(_) | Self::RootPackage(_)
+ )
+ }
+
+ /// A real `CompletePackage` or `RootPackage`.
+ pub fn is_complete_real(&self) -> bool {
+ matches!(self, Self::CompletePackage(_) | Self::RootPackage(_))
+ }
+
+ /// A real `RootPackage`.
+ pub fn is_root_real(&self) -> bool {
+ matches!(self, Self::RootPackage(_))
+ }
+
+ /// A `CompleteAliasPackage` or `RootAliasPackage`.
+ pub fn is_complete_alias(&self) -> bool {
+ matches!(
+ self,
+ Self::CompleteAliasPackage(_) | Self::RootAliasPackage(_)
+ )
+ }
+
+ /// A `RootAliasPackage`.
+ pub fn is_root_alias(&self) -> bool {
+ matches!(self, Self::RootAliasPackage(_))
+ }
+}
+
+macro_rules! delegate_package_interface_to_inner {
+ ($Type:ty, $field:ident) => {
+ impl crate::package::PackageInterface for $Type {
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ fn get_name(&self) -> &str {
+ self.$field.get_name()
+ }
+ fn get_pretty_name(&self) -> &str {
+ self.$field.get_pretty_name()
+ }
+ fn get_names(&self, provides: bool) -> Vec<String> {
+ self.$field.get_names(provides)
+ }
+ fn set_id(&mut self, id: i64) {
+ self.$field.set_id(id);
+ }
+ fn get_id(&self) -> i64 {
+ self.$field.get_id()
+ }
+ fn is_dev(&self) -> bool {
+ self.$field.is_dev()
+ }
+ fn get_type(&self) -> &str {
+ self.$field.get_type()
+ }
+ fn get_target_dir(&self) -> Option<&str> {
+ self.$field.get_target_dir()
+ }
+ fn get_extra(&self) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.$field.get_extra()
+ }
+ fn set_installation_source(&mut self, r#type: Option<String>) {
+ self.$field.set_installation_source(r#type);
+ }
+ fn get_installation_source(&self) -> Option<&str> {
+ self.$field.get_installation_source()
+ }
+ fn get_source_type(&self) -> Option<&str> {
+ self.$field.get_source_type()
+ }
+ fn get_source_url(&self) -> Option<&str> {
+ self.$field.get_source_url()
+ }
+ fn get_source_urls(&self) -> Vec<String> {
+ self.$field.get_source_urls()
+ }
+ fn get_source_reference(&self) -> Option<&str> {
+ self.$field.get_source_reference()
+ }
+ fn get_source_mirrors(
+ &self,
+ ) -> Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>> {
+ self.$field.get_source_mirrors()
+ }
+ fn set_source_mirrors(
+ &mut self,
+ mirrors: Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>>,
+ ) {
+ self.$field.set_source_mirrors(mirrors);
+ }
+ fn get_dist_type(&self) -> Option<&str> {
+ self.$field.get_dist_type()
+ }
+ fn get_dist_url(&self) -> Option<&str> {
+ self.$field.get_dist_url()
+ }
+ fn get_dist_urls(&self) -> Vec<String> {
+ self.$field.get_dist_urls()
+ }
+ fn get_dist_reference(&self) -> Option<&str> {
+ self.$field.get_dist_reference()
+ }
+ fn get_dist_sha1_checksum(&self) -> Option<&str> {
+ self.$field.get_dist_sha1_checksum()
+ }
+ fn get_dist_mirrors(
+ &self,
+ ) -> Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>> {
+ self.$field.get_dist_mirrors()
+ }
+ fn set_dist_mirrors(
+ &mut self,
+ mirrors: Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>>,
+ ) {
+ self.$field.set_dist_mirrors(mirrors);
+ }
+ fn get_version(&self) -> &str {
+ self.$field.get_version()
+ }
+ fn get_pretty_version(&self) -> &str {
+ self.$field.get_pretty_version()
+ }
+ fn get_full_pretty_version(&self, truncate: bool, display_mode: i64) -> String {
+ self.$field.get_full_pretty_version(truncate, display_mode)
+ }
+ fn get_release_date(&self) -> Option<chrono::DateTime<chrono::Utc>> {
+ self.$field.get_release_date()
+ }
+ fn get_stability(&self) -> &str {
+ self.$field.get_stability()
+ }
+ fn get_requires(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.$field.get_requires()
+ }
+ fn get_conflicts(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.$field.get_conflicts()
+ }
+ fn get_provides(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.$field.get_provides()
+ }
+ fn get_replaces(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.$field.get_replaces()
+ }
+ fn get_dev_requires(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.$field.get_dev_requires()
+ }
+ fn get_suggests(&self) -> indexmap::IndexMap<String, String> {
+ self.$field.get_suggests()
+ }
+ fn get_autoload(&self) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.$field.get_autoload()
+ }
+ fn get_dev_autoload(&self) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.$field.get_dev_autoload()
+ }
+ fn get_include_paths(&self) -> Vec<String> {
+ self.$field.get_include_paths()
+ }
+ fn get_php_ext(
+ &self,
+ ) -> Option<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>> {
+ self.$field.get_php_ext()
+ }
+ fn set_repository(
+ &mut self,
+ repository: Box<dyn crate::repository::RepositoryInterface>,
+ ) -> anyhow::Result<()> {
+ self.$field.set_repository(repository)
+ }
+ fn get_repository(&self) -> Option<&dyn crate::repository::RepositoryInterface> {
+ self.$field.get_repository()
+ }
+ fn get_binaries(&self) -> Vec<String> {
+ self.$field.get_binaries()
+ }
+ fn get_unique_name(&self) -> String {
+ self.$field.get_unique_name()
+ }
+ fn get_notification_url(&self) -> Option<&str> {
+ self.$field.get_notification_url()
+ }
+ fn get_pretty_string(&self) -> String {
+ self.$field.get_pretty_string()
+ }
+ fn is_default_branch(&self) -> bool {
+ self.$field.is_default_branch()
+ }
+ fn get_transport_options(
+ &self,
+ ) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.$field.get_transport_options()
+ }
+ fn set_transport_options(
+ &mut self,
+ options: indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>,
+ ) {
+ self.$field.set_transport_options(options);
+ }
+ fn set_source_reference(&mut self, reference: Option<String>) {
+ self.$field.set_source_reference(reference);
+ }
+ fn set_dist_url(&mut self, url: Option<String>) {
+ self.$field.set_dist_url(url);
+ }
+ fn set_dist_type(&mut self, r#type: Option<String>) {
+ self.$field.set_dist_type(r#type);
+ }
+ fn set_dist_reference(&mut self, reference: Option<String>) {
+ self.$field.set_dist_reference(reference);
+ }
+ fn set_source_dist_references(&mut self, reference: &str) {
+ self.$field.set_source_dist_references(reference);
+ }
+ }
+ };
+}
+pub(crate) use delegate_package_interface_to_inner;
+
+macro_rules! impl_package_interface_handle {
+ ($Handle:ty) => {
+ impl $Handle {
+ pub fn get_name(&self) -> String {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_name()
+ .to_string()
+ }
+
+ pub fn get_pretty_name(&self) -> String {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_pretty_name()
+ .to_string()
+ }
+
+ pub fn get_names(&self, provides: bool) -> Vec<String> {
+ self.0.borrow().as_package_interface().get_names(provides)
+ }
+
+ pub fn set_id(&self, id: i64) {
+ self.0.borrow_mut().as_package_interface_mut().set_id(id);
+ }
+
+ pub fn get_id(&self) -> i64 {
+ self.0.borrow().as_package_interface().get_id()
+ }
+
+ /// PHP `BasePackage::$id` accessor; alias of [`get_id`](Self::get_id).
+ pub fn id(&self) -> i64 {
+ self.0.borrow().as_package_interface().get_id()
+ }
+
+ pub fn is_dev(&self) -> bool {
+ self.0.borrow().as_package_interface().is_dev()
+ }
+
+ pub fn get_type(&self) -> String {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_type()
+ .to_string()
+ }
+
+ pub fn get_target_dir(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_target_dir()
+ .map(str::to_string)
+ }
+
+ pub fn get_extra(&self) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.0.borrow().as_package_interface().get_extra()
+ }
+
+ pub fn set_installation_source(&self, r#type: Option<String>) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_installation_source(r#type);
+ }
+
+ pub fn get_installation_source(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_installation_source()
+ .map(str::to_string)
+ }
+
+ pub fn get_source_type(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_source_type()
+ .map(str::to_string)
+ }
+
+ pub fn get_source_url(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_source_url()
+ .map(str::to_string)
+ }
+
+ pub fn get_source_urls(&self) -> Vec<String> {
+ self.0.borrow().as_package_interface().get_source_urls()
+ }
+
+ pub fn get_source_reference(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_source_reference()
+ .map(str::to_string)
+ }
+
+ pub fn get_source_mirrors(
+ &self,
+ ) -> Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>> {
+ self.0.borrow().as_package_interface().get_source_mirrors()
+ }
+
+ pub fn set_source_mirrors(
+ &self,
+ mirrors: Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_source_mirrors(mirrors);
+ }
+
+ pub fn get_dist_type(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_dist_type()
+ .map(str::to_string)
+ }
+
+ pub fn get_dist_url(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_dist_url()
+ .map(str::to_string)
+ }
+
+ pub fn get_dist_urls(&self) -> Vec<String> {
+ self.0.borrow().as_package_interface().get_dist_urls()
+ }
+
+ pub fn get_dist_reference(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_dist_reference()
+ .map(str::to_string)
+ }
+
+ pub fn get_dist_sha1_checksum(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_dist_sha1_checksum()
+ .map(str::to_string)
+ }
+
+ pub fn get_dist_mirrors(
+ &self,
+ ) -> Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>> {
+ self.0.borrow().as_package_interface().get_dist_mirrors()
+ }
+
+ pub fn set_dist_mirrors(
+ &self,
+ mirrors: Option<Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_dist_mirrors(mirrors);
+ }
+
+ pub fn get_version(&self) -> String {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_version()
+ .to_string()
+ }
+
+ pub fn get_pretty_version(&self) -> String {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_pretty_version()
+ .to_string()
+ }
+
+ pub fn get_full_pretty_version(&self, truncate: bool, display_mode: i64) -> String {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_full_pretty_version(truncate, display_mode)
+ }
+
+ pub fn get_release_date(&self) -> Option<chrono::DateTime<chrono::Utc>> {
+ self.0.borrow().as_package_interface().get_release_date()
+ }
+
+ pub fn get_stability(&self) -> String {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_stability()
+ .to_string()
+ }
+
+ pub fn get_requires(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.0.borrow().as_package_interface().get_requires()
+ }
+
+ pub fn get_conflicts(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.0.borrow().as_package_interface().get_conflicts()
+ }
+
+ pub fn get_provides(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.0.borrow().as_package_interface().get_provides()
+ }
+
+ pub fn get_replaces(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.0.borrow().as_package_interface().get_replaces()
+ }
+
+ pub fn get_dev_requires(&self) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.0.borrow().as_package_interface().get_dev_requires()
+ }
+
+ pub fn get_suggests(&self) -> indexmap::IndexMap<String, String> {
+ self.0.borrow().as_package_interface().get_suggests()
+ }
+
+ pub fn get_links_for_type(
+ &self,
+ link_type: &str,
+ ) -> indexmap::IndexMap<String, crate::package::Link> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_links_for_type(link_type)
+ }
+
+ pub fn get_autoload(&self) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.0.borrow().as_package_interface().get_autoload()
+ }
+
+ pub fn get_dev_autoload(
+ &self,
+ ) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.0.borrow().as_package_interface().get_dev_autoload()
+ }
+
+ pub fn get_include_paths(&self) -> Vec<String> {
+ self.0.borrow().as_package_interface().get_include_paths()
+ }
+
+ pub fn get_php_ext(
+ &self,
+ ) -> Option<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>> {
+ self.0.borrow().as_package_interface().get_php_ext()
+ }
+
+ pub fn set_repository(
+ &self,
+ repository: Box<dyn crate::repository::RepositoryInterface>,
+ ) -> anyhow::Result<()> {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_repository(repository)
+ }
+
+ pub fn get_binaries(&self) -> Vec<String> {
+ self.0.borrow().as_package_interface().get_binaries()
+ }
+
+ pub fn get_unique_name(&self) -> String {
+ self.0.borrow().as_package_interface().get_unique_name()
+ }
+
+ pub fn get_notification_url(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_notification_url()
+ .map(str::to_string)
+ }
+
+ pub fn get_pretty_string(&self) -> String {
+ self.0.borrow().as_package_interface().get_pretty_string()
+ }
+
+ pub fn is_default_branch(&self) -> bool {
+ self.0.borrow().as_package_interface().is_default_branch()
+ }
+
+ pub fn get_transport_options(
+ &self,
+ ) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.0
+ .borrow()
+ .as_package_interface()
+ .get_transport_options()
+ }
+
+ pub fn set_transport_options(
+ &self,
+ options: indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_transport_options(options);
+ }
+
+ pub fn set_source_reference(&self, reference: Option<String>) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_source_reference(reference);
+ }
+
+ pub fn set_dist_url(&self, url: Option<String>) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_dist_url(url);
+ }
+
+ pub fn set_dist_type(&self, r#type: Option<String>) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_dist_type(r#type);
+ }
+
+ pub fn set_dist_reference(&self, reference: Option<String>) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_dist_reference(reference);
+ }
+
+ pub fn set_source_dist_references(&self, reference: &str) {
+ self.0
+ .borrow_mut()
+ .as_package_interface_mut()
+ .set_source_dist_references(reference);
+ }
+ }
+ };
+}
+
+macro_rules! impl_complete_package_interface_handle {
+ ($Handle:ty) => {
+ impl $Handle {
+ pub fn get_scripts(&self) -> indexmap::IndexMap<String, Vec<String>> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_scripts()
+ }
+
+ pub fn set_scripts(&self, scripts: indexmap::IndexMap<String, Vec<String>>) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_scripts(scripts);
+ }
+
+ pub fn get_repositories(
+ &self,
+ ) -> Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_repositories()
+ }
+
+ pub fn set_repositories(
+ &self,
+ repositories: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_repositories(repositories);
+ }
+
+ pub fn get_license(&self) -> Vec<String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_license()
+ }
+
+ pub fn set_license(&self, license: Vec<String>) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_license(license);
+ }
+
+ pub fn get_keywords(&self) -> Vec<String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_keywords()
+ }
+
+ pub fn set_keywords(&self, keywords: Vec<String>) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_keywords(keywords);
+ }
+
+ pub fn get_description(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_description()
+ .map(str::to_string)
+ }
+
+ pub fn set_description(&self, description: String) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_description(description);
+ }
+
+ pub fn get_homepage(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_homepage()
+ .map(str::to_string)
+ }
+
+ pub fn set_homepage(&self, homepage: String) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_homepage(homepage);
+ }
+
+ pub fn get_authors(&self) -> Vec<indexmap::IndexMap<String, String>> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_authors()
+ }
+
+ pub fn set_authors(&self, authors: Vec<indexmap::IndexMap<String, String>>) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_authors(authors);
+ }
+
+ pub fn get_support(&self) -> indexmap::IndexMap<String, String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_support()
+ }
+
+ pub fn set_support(&self, support: indexmap::IndexMap<String, String>) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_support(support);
+ }
+
+ pub fn get_funding(
+ &self,
+ ) -> Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_funding()
+ }
+
+ pub fn set_funding(
+ &self,
+ funding: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_funding(funding);
+ }
+
+ pub fn is_abandoned(&self) -> bool {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .is_abandoned()
+ }
+
+ pub fn get_replacement_package(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_replacement_package()
+ .map(str::to_string)
+ }
+
+ pub fn set_abandoned(&self, abandoned: shirabe_php_shim::PhpMixed) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_abandoned(abandoned);
+ }
+
+ pub fn get_archive_name(&self) -> Option<String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_archive_name()
+ .map(str::to_string)
+ }
+
+ pub fn set_archive_name(&self, name: String) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_archive_name(name);
+ }
+
+ pub fn get_archive_excludes(&self) -> Vec<String> {
+ self.0
+ .borrow()
+ .as_complete_package_interface()
+ .expect("CompletePackage handle invariant")
+ .get_archive_excludes()
+ }
+
+ pub fn set_archive_excludes(&self, excludes: Vec<String>) {
+ self.0
+ .borrow_mut()
+ .as_complete_package_interface_mut()
+ .expect("CompletePackage handle invariant")
+ .set_archive_excludes(excludes);
+ }
+ }
+ };
+}
+
+macro_rules! impl_root_package_interface_handle {
+ ($Handle:ty) => {
+ impl $Handle {
+ pub fn get_aliases(&self) -> Vec<indexmap::IndexMap<String, String>> {
+ self.0
+ .borrow()
+ .as_root_package_interface()
+ .expect("RootPackage handle invariant")
+ .get_aliases()
+ .to_vec()
+ }
+
+ pub fn get_minimum_stability(&self) -> String {
+ self.0
+ .borrow()
+ .as_root_package_interface()
+ .expect("RootPackage handle invariant")
+ .get_minimum_stability()
+ .to_string()
+ }
+
+ pub fn get_stability_flags(&self) -> indexmap::IndexMap<String, i64> {
+ self.0
+ .borrow()
+ .as_root_package_interface()
+ .expect("RootPackage handle invariant")
+ .get_stability_flags()
+ .clone()
+ }
+
+ pub fn get_references(&self) -> indexmap::IndexMap<String, String> {
+ self.0
+ .borrow()
+ .as_root_package_interface()
+ .expect("RootPackage handle invariant")
+ .get_references()
+ .clone()
+ }
+
+ pub fn get_prefer_stable(&self) -> bool {
+ self.0
+ .borrow()
+ .as_root_package_interface()
+ .expect("RootPackage handle invariant")
+ .get_prefer_stable()
+ }
+
+ pub fn get_config(&self) -> indexmap::IndexMap<String, shirabe_php_shim::PhpMixed> {
+ self.0
+ .borrow()
+ .as_root_package_interface()
+ .expect("RootPackage handle invariant")
+ .get_config()
+ .clone()
+ }
+
+ pub fn set_requires(&self, requires: Vec<crate::package::Link>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_requires(requires);
+ }
+
+ pub fn set_dev_requires(&self, dev_requires: Vec<crate::package::Link>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_dev_requires(dev_requires);
+ }
+
+ pub fn set_conflicts(&self, conflicts: Vec<crate::package::Link>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_conflicts(conflicts);
+ }
+
+ pub fn set_provides(&self, provides: Vec<crate::package::Link>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_provides(provides);
+ }
+
+ pub fn set_replaces(&self, replaces: Vec<crate::package::Link>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_replaces(replaces);
+ }
+
+ pub fn set_autoload(
+ &self,
+ autoload: indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_autoload(autoload);
+ }
+
+ pub fn set_dev_autoload(
+ &self,
+ dev_autoload: indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_dev_autoload(dev_autoload);
+ }
+
+ pub fn set_stability_flags(&self, stability_flags: indexmap::IndexMap<String, i64>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_stability_flags(stability_flags);
+ }
+
+ pub fn set_minimum_stability(&self, minimum_stability: String) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_minimum_stability(minimum_stability);
+ }
+
+ pub fn set_prefer_stable(&self, prefer_stable: bool) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_prefer_stable(prefer_stable);
+ }
+
+ pub fn set_config(
+ &self,
+ config: indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>,
+ ) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_config(config);
+ }
+
+ pub fn set_references(&self, references: indexmap::IndexMap<String, String>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_references(references);
+ }
+
+ pub fn set_aliases(&self, aliases: Vec<indexmap::IndexMap<String, String>>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_aliases(aliases);
+ }
+
+ pub fn set_suggests(&self, suggests: indexmap::IndexMap<String, String>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_suggests(suggests);
+ }
+
+ pub fn set_extra(&self, extra: indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>) {
+ self.0
+ .borrow_mut()
+ .as_root_package_interface_mut()
+ .expect("RootPackage handle invariant")
+ .set_extra(extra);
+ }
+ }
+ };
+}
+
+macro_rules! impl_handle_common {
+ ($Handle:ty) => {
+ impl $Handle {
+ pub fn as_rc(&self) -> &std::rc::Rc<std::cell::RefCell<AnyPackage>> {
+ &self.0
+ }
+
+ pub fn from_rc_unchecked(rc: std::rc::Rc<std::cell::RefCell<AnyPackage>>) -> Self {
+ Self(rc)
+ }
+
+ /// Stable identity usable as a map key (PHP `spl_object_hash`).
+ pub fn ptr_id(&self) -> usize {
+ std::rc::Rc::as_ptr(&self.0) as *const () as usize
+ }
+
+ /// PHP `===` (reference identity).
+ pub fn ptr_eq(&self, other: &Self) -> bool {
+ std::rc::Rc::ptr_eq(&self.0, &other.0)
+ }
+ }
+
+ impl PartialEq for $Handle {
+ fn eq(&self, other: &Self) -> bool {
+ std::rc::Rc::ptr_eq(&self.0, &other.0)
+ }
+ }
+
+ impl Eq for $Handle {}
+
+ impl std::hash::Hash for $Handle {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.ptr_id().hash(state);
+ }
+ }
+
+ impl std::fmt::Display for $Handle {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.0.borrow().as_package_interface(), f)
+ }
+ }
+ };
+}
+
+macro_rules! impl_handle_upcast {
+ ($Narrow:ty => $Wide:ty) => {
+ impl From<$Narrow> for $Wide {
+ fn from(h: $Narrow) -> Self {
+ Self(h.0)
+ }
+ }
+ };
+}
+
+/// Shared reference to any package. Corresponds to PHP `PackageInterface`.
+#[derive(Debug, Clone)]
+pub struct PackageInterfaceHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to any package. Corresponds to PHP `BasePackage`.
+/// It is exactly the same as `PackageInterface` in Shirabe. It is only for mirroing PHP type
+/// annotations.
+pub type BasePackageHandle = PackageInterfaceHandle;
+
+/// Shared reference to a complete package. Corresponds to PHP `CompletePackageInterface`.
+#[derive(Debug, Clone)]
+pub struct CompletePackageInterfaceHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to a root package. Corresponds to PHP `RootPackageInterface`.
+#[derive(Debug, Clone)]
+pub struct RootPackageInterfaceHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to a real (non-alias) package. Corresponds to PHP `Package`.
+#[derive(Debug, Clone)]
+pub struct PackageHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to a real complete package. Corresponds to PHP `CompletePackage`.
+#[derive(Debug, Clone)]
+pub struct CompletePackageHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to a real root package. Corresponds to PHP `RootPackage`.
+#[derive(Debug, Clone)]
+pub struct RootPackageHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to an alias package. Corresponds to PHP `AliasPackage`.
+#[derive(Debug, Clone)]
+pub struct AliasPackageHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to a complete alias package. Corresponds to PHP `CompleteAliasPackage`.
+#[derive(Debug, Clone)]
+pub struct CompleteAliasPackageHandle(Rc<RefCell<AnyPackage>>);
+
+/// Shared reference to a root alias package. Corresponds to PHP `RootAliasPackage`.
+#[derive(Debug, Clone)]
+pub struct RootAliasPackageHandle(Rc<RefCell<AnyPackage>>);
+
+impl_handle_common!(PackageInterfaceHandle);
+impl_handle_common!(CompletePackageInterfaceHandle);
+impl_handle_common!(RootPackageInterfaceHandle);
+impl_handle_common!(PackageHandle);
+impl_handle_common!(CompletePackageHandle);
+impl_handle_common!(RootPackageHandle);
+impl_handle_common!(AliasPackageHandle);
+impl_handle_common!(CompleteAliasPackageHandle);
+impl_handle_common!(RootAliasPackageHandle);
+
+impl_package_interface_handle!(PackageInterfaceHandle);
+impl_package_interface_handle!(CompletePackageInterfaceHandle);
+impl_package_interface_handle!(RootPackageInterfaceHandle);
+impl_package_interface_handle!(PackageHandle);
+impl_package_interface_handle!(CompletePackageHandle);
+impl_package_interface_handle!(RootPackageHandle);
+impl_package_interface_handle!(AliasPackageHandle);
+impl_package_interface_handle!(CompleteAliasPackageHandle);
+impl_package_interface_handle!(RootAliasPackageHandle);
+
+impl_complete_package_interface_handle!(CompletePackageInterfaceHandle);
+impl_complete_package_interface_handle!(RootPackageInterfaceHandle);
+impl_complete_package_interface_handle!(CompletePackageHandle);
+impl_complete_package_interface_handle!(RootPackageHandle);
+impl_complete_package_interface_handle!(CompleteAliasPackageHandle);
+impl_complete_package_interface_handle!(RootAliasPackageHandle);
+
+impl_root_package_interface_handle!(RootPackageInterfaceHandle);
+impl_root_package_interface_handle!(RootPackageHandle);
+impl_root_package_interface_handle!(RootAliasPackageHandle);
+
+impl_handle_upcast!(CompletePackageInterfaceHandle => PackageInterfaceHandle);
+
+impl_handle_upcast!(RootPackageInterfaceHandle => CompletePackageInterfaceHandle);
+impl_handle_upcast!(RootPackageInterfaceHandle => PackageInterfaceHandle);
+
+impl_handle_upcast!(PackageHandle => PackageInterfaceHandle);
+
+impl_handle_upcast!(CompletePackageHandle => PackageHandle);
+impl_handle_upcast!(CompletePackageHandle => CompletePackageInterfaceHandle);
+impl_handle_upcast!(CompletePackageHandle => PackageInterfaceHandle);
+
+impl_handle_upcast!(RootPackageHandle => CompletePackageHandle);
+impl_handle_upcast!(RootPackageHandle => PackageHandle);
+impl_handle_upcast!(RootPackageHandle => RootPackageInterfaceHandle);
+impl_handle_upcast!(RootPackageHandle => CompletePackageInterfaceHandle);
+impl_handle_upcast!(RootPackageHandle => PackageInterfaceHandle);
+
+impl_handle_upcast!(AliasPackageHandle => PackageInterfaceHandle);
+
+impl_handle_upcast!(CompleteAliasPackageHandle => AliasPackageHandle);
+impl_handle_upcast!(CompleteAliasPackageHandle => CompletePackageInterfaceHandle);
+impl_handle_upcast!(CompleteAliasPackageHandle => PackageInterfaceHandle);
+
+impl_handle_upcast!(RootAliasPackageHandle => CompleteAliasPackageHandle);
+impl_handle_upcast!(RootAliasPackageHandle => AliasPackageHandle);
+impl_handle_upcast!(RootAliasPackageHandle => RootPackageInterfaceHandle);
+impl_handle_upcast!(RootAliasPackageHandle => CompletePackageInterfaceHandle);
+impl_handle_upcast!(RootAliasPackageHandle => PackageInterfaceHandle);
+
+macro_rules! impl_handle_downcasts {
+ ($Handle:ty) => {
+ impl $Handle {
+ /// PHP `$p instanceof AliasPackage`.
+ pub fn as_alias(&self) -> Option<AliasPackageHandle> {
+ self.0
+ .borrow()
+ .is_alias()
+ .then(|| AliasPackageHandle(self.0.clone()))
+ }
+
+ /// PHP `$p instanceof CompletePackageInterface`.
+ pub fn as_complete(&self) -> Option<CompletePackageInterfaceHandle> {
+ self.0
+ .borrow()
+ .is_complete()
+ .then(|| CompletePackageInterfaceHandle(self.0.clone()))
+ }
+
+ /// PHP `$p instanceof RootPackageInterface`.
+ pub fn as_root(&self) -> Option<RootPackageInterfaceHandle> {
+ self.0
+ .borrow()
+ .is_root()
+ .then(|| RootPackageInterfaceHandle(self.0.clone()))
+ }
+
+ /// PHP `$p instanceof Package` (real, non-alias).
+ pub fn as_package(&self) -> Option<PackageHandle> {
+ self.0
+ .borrow()
+ .is_real()
+ .then(|| PackageHandle(self.0.clone()))
+ }
+
+ /// PHP `$p instanceof CompletePackage` (real).
+ pub fn as_complete_package(&self) -> Option<CompletePackageHandle> {
+ self.0
+ .borrow()
+ .is_complete_real()
+ .then(|| CompletePackageHandle(self.0.clone()))
+ }
+
+ /// PHP `$p instanceof RootPackage` (real).
+ pub fn as_root_package(&self) -> Option<RootPackageHandle> {
+ self.0
+ .borrow()
+ .is_root_real()
+ .then(|| RootPackageHandle(self.0.clone()))
+ }
+
+ /// PHP `$p instanceof CompleteAliasPackage`.
+ pub fn as_complete_alias_package(&self) -> Option<CompleteAliasPackageHandle> {
+ self.0
+ .borrow()
+ .is_complete_alias()
+ .then(|| CompleteAliasPackageHandle(self.0.clone()))
+ }
+
+ /// PHP `$p instanceof RootAliasPackage`.
+ pub fn as_root_alias_package(&self) -> Option<RootAliasPackageHandle> {
+ self.0
+ .borrow()
+ .is_root_alias()
+ .then(|| RootAliasPackageHandle(self.0.clone()))
+ }
+
+ pub fn is_alias(&self) -> bool {
+ self.0.borrow().is_alias()
+ }
+ }
+ };
+}
+
+impl_handle_downcasts!(PackageInterfaceHandle);
+
+impl PackageHandle {
+ pub fn from_package(package: Package) -> Self {
+ Self(Rc::new(RefCell::new(AnyPackage::Package(package))))
+ }
+
+ pub fn new(name: String, version: String, pretty_version: String) -> Self {
+ Self::from_package(Package::new(name, version, pretty_version))
+ }
+}
+
+impl CompletePackageHandle {
+ pub fn from_complete_package(package: CompletePackage) -> Self {
+ Self(Rc::new(RefCell::new(AnyPackage::CompletePackage(package))))
+ }
+
+ pub fn new(name: String, version: String, pretty_version: String) -> Self {
+ Self::from_complete_package(CompletePackage::new(name, version, pretty_version))
+ }
+}
+
+impl RootPackageHandle {
+ pub fn from_root_package(package: RootPackage) -> Self {
+ Self(Rc::new(RefCell::new(AnyPackage::RootPackage(package))))
+ }
+
+ pub fn new(name: String, version: String, pretty_version: String) -> Self {
+ Self::from_root_package(RootPackage::new(name, version, pretty_version))
+ }
+}
+
+impl AliasPackageHandle {
+ pub fn from_alias_package(package: AliasPackage) -> Self {
+ Self(Rc::new(RefCell::new(AnyPackage::AliasPackage(package))))
+ }
+
+ pub fn new(alias_of: PackageHandle, version: String, pretty_version: String) -> Self {
+ Self::from_alias_package(AliasPackage::new(alias_of, version, pretty_version))
+ }
+
+ /// PHP `getAliasOf()`. The aliased package is always real.
+ pub fn get_alias_of(&self) -> PackageHandle {
+ match &*self.0.borrow() {
+ AnyPackage::AliasPackage(p) => p.alias_of.clone(),
+ AnyPackage::CompleteAliasPackage(p) => PackageHandle::from(p.alias_of.clone()),
+ AnyPackage::RootAliasPackage(p) => PackageHandle::from(p.alias_of.clone()),
+ _ => unreachable!("AliasPackageHandle invariant violated"),
+ }
+ }
+
+ pub fn set_root_package_alias(&self, value: bool) {
+ match &mut *self.0.borrow_mut() {
+ AnyPackage::AliasPackage(p) => p.set_root_package_alias(value),
+ AnyPackage::CompleteAliasPackage(p) => p.set_root_package_alias(value),
+ AnyPackage::RootAliasPackage(p) => p.set_root_package_alias(value),
+ _ => unreachable!("AliasPackageHandle invariant violated"),
+ }
+ }
+
+ pub fn is_root_package_alias(&self) -> bool {
+ match &*self.0.borrow() {
+ AnyPackage::AliasPackage(p) => p.is_root_package_alias(),
+ AnyPackage::CompleteAliasPackage(p) => p.is_root_package_alias(),
+ AnyPackage::RootAliasPackage(p) => p.is_root_package_alias(),
+ _ => unreachable!("AliasPackageHandle invariant violated"),
+ }
+ }
+
+ pub fn has_self_version_requires(&self) -> bool {
+ match &*self.0.borrow() {
+ AnyPackage::AliasPackage(p) => p.has_self_version_requires(),
+ AnyPackage::CompleteAliasPackage(p) => p.has_self_version_requires(),
+ AnyPackage::RootAliasPackage(p) => p.has_self_version_requires(),
+ _ => unreachable!("AliasPackageHandle invariant violated"),
+ }
+ }
+}
+
+impl CompleteAliasPackageHandle {
+ pub fn from_complete_alias_package(package: CompleteAliasPackage) -> Self {
+ Self(Rc::new(RefCell::new(AnyPackage::CompleteAliasPackage(
+ package,
+ ))))
+ }
+
+ pub fn new(alias_of: CompletePackageHandle, version: String, pretty_version: String) -> Self {
+ Self::from_complete_alias_package(CompleteAliasPackage::new(
+ alias_of,
+ version,
+ pretty_version,
+ ))
+ }
+
+ /// PHP `getAliasOf()` narrowed to `CompletePackage`.
+ pub fn get_alias_of(&self) -> CompletePackageHandle {
+ match &*self.0.borrow() {
+ AnyPackage::CompleteAliasPackage(p) => p.alias_of.clone(),
+ AnyPackage::RootAliasPackage(p) => CompletePackageHandle::from(p.alias_of.clone()),
+ _ => unreachable!("CompleteAliasPackageHandle invariant violated"),
+ }
+ }
+}
+
+impl RootAliasPackageHandle {
+ pub fn from_root_alias_package(package: RootAliasPackage) -> Self {
+ Self(Rc::new(RefCell::new(AnyPackage::RootAliasPackage(package))))
+ }
+
+ pub fn new(alias_of: RootPackageHandle, version: String, pretty_version: String) -> Self {
+ Self::from_root_alias_package(RootAliasPackage::new(alias_of, version, pretty_version))
+ }
+
+ /// PHP `getAliasOf()` narrowed to `RootPackage`.
+ pub fn get_alias_of(&self) -> RootPackageHandle {
+ match &*self.0.borrow() {
+ AnyPackage::RootAliasPackage(p) => p.alias_of.clone(),
+ _ => unreachable!("RootAliasPackageHandle invariant violated"),
+ }
+ }
+}
diff --git a/crates/shirabe/src/package/loader/array_loader.rs b/crates/shirabe/src/package/loader/array_loader.rs
index 87d6e35..e1cc60b 100644
--- a/crates/shirabe/src/package/loader/array_loader.rs
+++ b/crates/shirabe/src/package/loader/array_loader.rs
@@ -12,11 +12,14 @@ use shirabe_php_shim::{
use crate::package::CompleteAliasPackage;
use crate::package::CompletePackage;
+use crate::package::CompletePackageHandle;
use crate::package::CompletePackageInterface;
use crate::package::Link;
use crate::package::PackageInterface;
+use crate::package::PackageInterfaceHandle;
use crate::package::RootAliasPackage;
use crate::package::RootPackage;
+use crate::package::RootPackageHandle;
use crate::package::loader::LoaderInterface;
use crate::package::version::VersionParser;
use crate::package::{BasePackage, SUPPORTED_LINK_TYPES};
@@ -51,7 +54,7 @@ impl LoaderInterface for ArrayLoader {
&self,
mut config: IndexMap<String, PhpMixed>,
class: Option<String>,
- ) -> Result<Box<dyn BasePackage>> {
+ ) -> Result<PackageInterfaceHandle> {
let class = class.unwrap_or_else(|| "Composer\\Package\\CompletePackage".to_string());
if class != "Composer\\Package\\CompletePackage"
@@ -104,8 +107,8 @@ impl ArrayLoader {
pub fn load_packages(
&self,
versions: Vec<IndexMap<String, PhpMixed>>,
- ) -> Result<Vec<Box<dyn BasePackage>>> {
- let mut packages: Vec<Box<dyn BasePackage>> = vec![];
+ ) -> Result<Vec<PackageInterfaceHandle>> {
+ let mut packages: Vec<PackageInterfaceHandle> = vec![];
let mut link_cache: IndexMap<
String,
IndexMap<String, IndexMap<String, IndexMap<String, (String, Link)>>>,
@@ -226,7 +229,7 @@ impl ArrayLoader {
&self,
mut package: Box<CompletePackage>,
config: &mut IndexMap<String, PhpMixed>,
- ) -> Result<Box<dyn BasePackage>> {
+ ) -> Result<PackageInterfaceHandle> {
// PHP: if (!$package instanceof CompletePackage) — true by construction in Rust
// (create_object always returns Box<CompletePackage>); kept as a no-op for parity.
let _ = LogicException {
@@ -593,12 +596,20 @@ impl ArrayLoader {
// TODO(phase-b): `$package instanceof RootPackage` downcast from CompletePackage
let package_as_root: Option<RootPackage> = None;
if let Some(root) = package_as_root {
- let _ = RootAliasPackage::new(root, alias_normalized, pretty_alias);
+ let _ = RootAliasPackage::new(
+ RootPackageHandle::from_root_package(root),
+ alias_normalized,
+ pretty_alias,
+ );
// TODO(phase-b): return Box<RootAliasPackage> wrapped as Box<BasePackage>
todo!("phase-b: return RootAliasPackage as Box<BasePackage>")
}
- let _ = CompleteAliasPackage::new(*package, alias_normalized, pretty_alias);
+ let _ = CompleteAliasPackage::new(
+ CompletePackageHandle::from_complete_package(*package),
+ alias_normalized,
+ pretty_alias,
+ );
// TODO(phase-b): return Box<CompleteAliasPackage> wrapped as Box<BasePackage>
todo!("phase-b: return CompleteAliasPackage as Box<BasePackage>")
}
diff --git a/crates/shirabe/src/package/loader/json_loader.rs b/crates/shirabe/src/package/loader/json_loader.rs
index e0589bb..5f8cc4f 100644
--- a/crates/shirabe/src/package/loader/json_loader.rs
+++ b/crates/shirabe/src/package/loader/json_loader.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Package/Loader/JsonLoader.php
use crate::json::JsonFile;
-use crate::package::BasePackage;
+use crate::package::PackageInterfaceHandle;
use crate::package::loader::LoaderInterface;
use anyhow::Result;
use std::path::Path;
@@ -20,7 +20,7 @@ impl JsonLoader {
Self { loader }
}
- pub fn load(&self, json: JsonLoaderInput) -> Result<Box<dyn BasePackage>> {
+ pub fn load(&self, json: JsonLoaderInput) -> Result<PackageInterfaceHandle> {
let config = match json {
JsonLoaderInput::File(mut json_file) => json_file.read()?,
JsonLoaderInput::String(ref s) if Path::new(s).exists() => {
diff --git a/crates/shirabe/src/package/loader/loader_interface.rs b/crates/shirabe/src/package/loader/loader_interface.rs
index d10b7be..586905f 100644
--- a/crates/shirabe/src/package/loader/loader_interface.rs
+++ b/crates/shirabe/src/package/loader/loader_interface.rs
@@ -1,6 +1,6 @@
//! ref: composer/src/Composer/Package/Loader/LoaderInterface.php
-use crate::package::BasePackage;
+use crate::package::PackageInterfaceHandle;
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
@@ -9,5 +9,5 @@ pub trait LoaderInterface: std::fmt::Debug {
&self,
config: IndexMap<String, PhpMixed>,
class: Option<String>,
- ) -> anyhow::Result<Box<dyn BasePackage>>;
+ ) -> anyhow::Result<PackageInterfaceHandle>;
}
diff --git a/crates/shirabe/src/package/loader/root_package_loader.rs b/crates/shirabe/src/package/loader/root_package_loader.rs
index 3cdaaa7..e235e31 100644
--- a/crates/shirabe/src/package/loader/root_package_loader.rs
+++ b/crates/shirabe/src/package/loader/root_package_loader.rs
@@ -66,7 +66,7 @@ impl RootPackageLoader {
config: IndexMap<String, Box<shirabe_php_shim::PhpMixed>>,
class: &str,
cwd: Option<&str>,
- ) -> anyhow::Result<Box<dyn PackageInterface>> {
+ ) -> anyhow::Result<crate::package::PackageInterfaceHandle> {
if class != "Composer\\Package\\RootPackage" {
shirabe_php_shim::trigger_error(
"The $class arg is deprecated, please reach out to Composer maintainers ASAP if you still need this.",
@@ -193,11 +193,14 @@ impl RootPackageLoader {
Some("Composer\\Package\\RootPackage".to_string()),
)?;
- // TODO(phase-b): as_any_mut is not available on BasePackage; downcast via Any is not
- // possible without it. Skipping real downcast and using todo!() placeholder.
+ // TODO(phase-c): mutating the loaded RootPackage through a PackageInterfaceHandle
+ // requires going through as_root_package() + a RefCell borrow; the inherent
+ // RootPackage mutators used below are not yet reachable that way.
let real_package: &mut RootPackage = {
let _ = &mut package;
- todo!("downcast Box<dyn BasePackage> to &mut RootPackage requires as_any_mut on trait")
+ todo!(
+ "mutate RootPackage through PackageInterfaceHandle (as_root_package + borrow_mut)"
+ )
};
if auto_versioned {
diff --git a/crates/shirabe/src/package/loader/validating_array_loader.rs b/crates/shirabe/src/package/loader/validating_array_loader.rs
index a2dd5a7..fbaa0f8 100644
--- a/crates/shirabe/src/package/loader/validating_array_loader.rs
+++ b/crates/shirabe/src/package/loader/validating_array_loader.rs
@@ -66,7 +66,7 @@ impl ValidatingArrayLoader {
&mut self,
config: IndexMap<String, Box<PhpMixed>>,
class: &str,
- ) -> anyhow::Result<Box<dyn BasePackage>> {
+ ) -> anyhow::Result<crate::package::PackageInterfaceHandle> {
self.errors = Vec::new();
self.warnings = Vec::new();
self.config = config.clone();
diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs
index 9522e55..bdeb391 100644
--- a/crates/shirabe/src/package/locker.rs
+++ b/crates/shirabe/src/package/locker.rs
@@ -15,11 +15,11 @@ use shirabe_php_shim::{
use crate::installer::InstallationManager;
use crate::io::IOInterface;
use crate::json::JsonFile;
-use crate::package::AliasPackage;
-use crate::package::BasePackage;
+use crate::package::BasePackageHandle;
use crate::package::CompleteAliasPackage;
use crate::package::Link;
use crate::package::PackageInterface;
+use crate::package::PackageInterfaceHandle;
use crate::package::RootPackageInterface;
use crate::package::dumper::ArrayDumper;
use crate::package::loader::ArrayLoader;
@@ -219,15 +219,15 @@ impl Locker {
false
};
if has_name {
- let mut package_by_name: IndexMap<String, Box<dyn BasePackage>> = IndexMap::new();
+ let mut package_by_name: IndexMap<String, BasePackageHandle> = IndexMap::new();
if let PhpMixed::List(list) = locked_packages {
for info in list {
if let PhpMixed::Array(m) = info.as_ref() {
let info_map: IndexMap<String, PhpMixed> =
m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect();
let package = self.loader.load(info_map, None)?;
- // TODO(phase-b): PHP shares the package between repository and map (Rc<dyn BasePackage>)
- let _name = package.get_name().to_string();
+ // PHP shares the package between repository and map; the handle is the shared Rc.
+ let _name = package.get_name();
let _ = (&mut packages, &mut package_by_name, package);
todo!(
"packages.add_package(package); package_by_name.insert(name, package); + AliasPackage downcast"
@@ -245,10 +245,11 @@ impl Locker {
.and_then(|v| v.as_string())
.unwrap_or("")
.to_string();
- // TODO(phase-b): Box<dyn BasePackage> is not Clone; PHP semantics need Rc<dyn BasePackage>
if let Some(base_pkg) = package_by_name.get(&alias_pkg_name) {
let mut alias_pkg = CompleteAliasPackage::new(
- todo!("phase-b: downcast Box<BasePackage> to CompletePackage"),
+ todo!(
+ "phase-c: narrow base_pkg handle to CompletePackageHandle"
+ ),
m.get("alias_normalized")
.and_then(|v| v.as_string())
.unwrap_or("")
@@ -463,8 +464,8 @@ impl Locker {
/// Locks provided data into lockfile.
pub fn set_lock_data(
&mut self,
- packages: Vec<Box<dyn PackageInterface>>,
- dev_packages: Option<Vec<Box<dyn PackageInterface>>>,
+ packages: Vec<PackageInterfaceHandle>,
+ dev_packages: Option<Vec<PackageInterfaceHandle>>,
platform_reqs: IndexMap<String, String>,
platform_dev_reqs: IndexMap<String, String>,
aliases: Vec<IndexMap<String, PhpMixed>>,
@@ -743,13 +744,11 @@ impl Locker {
}
/// @param PackageInterface[] $packages
- fn lock_packages(&mut self, packages: &[Box<dyn PackageInterface>]) -> Result<PhpMixed> {
+ fn lock_packages(&mut self, packages: &[PackageInterfaceHandle]) -> Result<PhpMixed> {
let mut locked: Vec<IndexMap<String, PhpMixed>> = vec![];
for package in packages {
- // TODO(phase-b): `$package instanceof AliasPackage` downcast
- let package_as_alias: Option<&AliasPackage> = None;
- if package_as_alias.is_some() {
+ if package.as_alias().is_some() {
continue;
}
@@ -767,15 +766,20 @@ impl Locker {
.into());
}
- let mut spec = self.dumper.dump(&**package);
+ let mut spec = self
+ .dumper
+ .dump(package.as_rc().borrow().as_package_interface());
spec.shift_remove("version_normalized");
// always move time to the end of the package definition
let time = spec.get("time").cloned();
spec.shift_remove("time");
- let time = if package.is_dev() && package.get_installation_source() == Some("source") {
+ let time = if package.is_dev()
+ && package.get_installation_source() == Some("source".to_string())
+ {
// use the exact commit time of the current reference if it's a dev package
- let pkg_time = self.get_package_time(&**package)?;
+ let pkg_time =
+ self.get_package_time(package.as_rc().borrow().as_package_interface())?;
pkg_time.map(PhpMixed::String).or(time)
} else {
time
@@ -976,11 +980,10 @@ impl Locker {
.find_packages_with_replacers_and_providers(&link.get_target(), None);
if !results.is_empty() {
- // TODO(phase-b): reset_first requires Clone on dyn BasePackage; PHP returns shared reference
- let provider: &Box<dyn BasePackage> =
- todo!("reset_first(&results) shared ref");
+ // PHP `reset($results)` returns the first shared package; clone the handle.
+ let provider: BasePackageHandle = results.first().unwrap().clone();
let _ = &results;
- let mut description = provider.get_pretty_version().to_string();
+ let mut description = provider.get_pretty_version();
if provider.get_name() != link.get_target() {
'outer: for (method, text) in [
("getReplaces", "replaced as %s by %s"),
diff --git a/crates/shirabe/src/package/mod.rs b/crates/shirabe/src/package/mod.rs
index 611f36a..903056f 100644
--- a/crates/shirabe/src/package/mod.rs
+++ b/crates/shirabe/src/package/mod.rs
@@ -6,6 +6,7 @@ pub mod complete_alias_package;
pub mod complete_package;
pub mod complete_package_interface;
pub mod dumper;
+pub mod handle;
pub mod link;
pub mod loader;
pub mod locker;
@@ -24,6 +25,7 @@ pub use complete_alias_package::*;
pub use complete_package::*;
pub use complete_package_interface::*;
pub use dumper::*;
+pub use handle::*;
pub use link::*;
pub use loader::*;
pub use locker::*;
diff --git a/crates/shirabe/src/package/package.rs b/crates/shirabe/src/package/package.rs
index 75b4e54..da8451e 100644
--- a/crates/shirabe/src/package/package.rs
+++ b/crates/shirabe/src/package/package.rs
@@ -570,10 +570,6 @@ impl BasePackage for Package {
fn take_repository(&mut self) -> Option<Box<dyn RepositoryInterface>> {
todo!()
}
-
- fn clone_box(&self) -> Box<dyn BasePackage> {
- todo!()
- }
}
impl std::fmt::Display for Package {
diff --git a/crates/shirabe/src/package/package_interface.rs b/crates/shirabe/src/package/package_interface.rs
index 1c9cf2e..97aac26 100644
--- a/crates/shirabe/src/package/package_interface.rs
+++ b/crates/shirabe/src/package/package_interface.rs
@@ -290,14 +290,6 @@ pub trait PackageInterface: std::fmt::Display + std::fmt::Debug {
/// Set dist and source references and update dist URL for ones that contain a reference
fn set_source_dist_references(&mut self, reference: &str);
- // clone_box was moved to BasePackage with a Box<dyn BasePackage> return type;
- // exposing it here too caused trait-method ambiguity at every BasePackage call site.
- // Callers holding `&dyn PackageInterface` (rather than `&dyn BasePackage`) can use
- // `clone_package_box` instead.
- fn clone_package_box(&self) -> Box<dyn PackageInterface> {
- todo!()
- }
-
fn as_alias_package(&self) -> Option<&crate::package::AliasPackage> {
None
}
diff --git a/crates/shirabe/src/package/root_alias_package.rs b/crates/shirabe/src/package/root_alias_package.rs
index d6dafa9..7298c1f 100644
--- a/crates/shirabe/src/package/root_alias_package.rs
+++ b/crates/shirabe/src/package/root_alias_package.rs
@@ -1,51 +1,77 @@
//! ref: composer/src/Composer/Package/RootAliasPackage.php
-use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
use crate::package::CompleteAliasPackage;
+use crate::package::CompletePackageHandle;
use crate::package::CompletePackageInterface;
use crate::package::Link;
-use crate::package::PackageInterface;
-use crate::package::RootPackage;
+use crate::package::RootPackageHandle;
use crate::package::RootPackageInterface;
-use crate::repository::RepositoryInterface;
+use crate::package::handle::delegate_package_interface_to_inner;
#[derive(Debug)]
pub struct RootAliasPackage {
inner: CompleteAliasPackage,
// overrides CompleteAliasPackage::alias_of with the more specific RootPackage type
- pub(crate) alias_of: RootPackage,
+ pub(crate) alias_of: RootPackageHandle,
}
impl RootAliasPackage {
- pub fn new(alias_of: RootPackage, version: String, pretty_version: String) -> Self {
- // TODO(phase-b): RootPackage.inner (CompletePackage) is not accessible here
- let inner: CompleteAliasPackage = todo!();
+ pub fn new(alias_of: RootPackageHandle, version: String, pretty_version: String) -> Self {
+ let inner = CompleteAliasPackage::new(
+ CompletePackageHandle::from(alias_of.clone()),
+ version,
+ pretty_version,
+ );
Self { inner, alias_of }
}
- pub fn get_alias_of(&self) -> &RootPackage {
- &self.alias_of
+ pub fn get_alias_of(&self) -> RootPackageHandle {
+ self.alias_of.clone()
+ }
+
+ pub fn set_root_package_alias(&mut self, value: bool) {
+ self.inner.set_root_package_alias(value);
+ }
+
+ pub fn is_root_package_alias(&self) -> bool {
+ self.inner.is_root_package_alias()
+ }
+
+ pub fn has_self_version_requires(&self) -> bool {
+ self.inner.has_self_version_requires()
+ }
+}
+
+delegate_package_interface_to_inner!(RootAliasPackage, inner);
+
+impl std::fmt::Display for RootAliasPackage {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(&self.inner, f)
}
}
impl RootPackageInterface for RootAliasPackage {
fn get_aliases(&self) -> &[IndexMap<String, String>] {
- self.alias_of.get_aliases()
+ todo!("RootAliasPackage::get_aliases cannot return a borrow across the aliasOf handle")
}
fn get_minimum_stability(&self) -> &str {
- self.alias_of.get_minimum_stability()
+ todo!(
+ "RootAliasPackage::get_minimum_stability cannot return &str across the aliasOf handle"
+ )
}
fn get_stability_flags(&self) -> &IndexMap<String, i64> {
- self.alias_of.get_stability_flags()
+ todo!(
+ "RootAliasPackage::get_stability_flags cannot return a borrow across the aliasOf handle"
+ )
}
fn get_references(&self) -> &IndexMap<String, String> {
- self.alias_of.get_references()
+ todo!("RootAliasPackage::get_references cannot return a borrow across the aliasOf handle")
}
fn get_prefer_stable(&self) -> bool {
@@ -53,31 +79,28 @@ impl RootPackageInterface for RootAliasPackage {
}
fn get_config(&self) -> &IndexMap<String, PhpMixed> {
- self.alias_of.get_config()
+ todo!("RootAliasPackage::get_config cannot return a borrow across the aliasOf handle")
}
fn set_requires(&mut self, requires: Vec<Link>) {
- // TODO(phase-b): self.inner.requires = self.replace_self_version_dependencies(requires.clone(), Link::TYPE_REQUIRE)
+ // TODO(phase-c): PHP re-derives the local links via
+ // replaceSelfVersionDependencies before forwarding to aliasOf.
self.alias_of.set_requires(requires);
}
fn set_dev_requires(&mut self, dev_requires: Vec<Link>) {
- // TODO(phase-b): self.inner.dev_requires = self.replace_self_version_dependencies(dev_requires.clone(), Link::TYPE_DEV_REQUIRE)
self.alias_of.set_dev_requires(dev_requires);
}
fn set_conflicts(&mut self, conflicts: Vec<Link>) {
- // TODO(phase-b): self.inner.conflicts = self.replace_self_version_dependencies(conflicts.clone(), Link::TYPE_CONFLICT)
self.alias_of.set_conflicts(conflicts);
}
fn set_provides(&mut self, provides: Vec<Link>) {
- // TODO(phase-b): self.inner.provides = self.replace_self_version_dependencies(provides.clone(), Link::TYPE_PROVIDE)
self.alias_of.set_provides(provides);
}
fn set_replaces(&mut self, replaces: Vec<Link>) {
- // TODO(phase-b): self.inner.replaces = self.replace_self_version_dependencies(replaces.clone(), Link::TYPE_REPLACE)
self.alias_of.set_replaces(replaces);
}
@@ -124,274 +147,102 @@ impl RootPackageInterface for RootAliasPackage {
impl CompletePackageInterface for RootAliasPackage {
fn get_scripts(&self) -> IndexMap<String, Vec<String>> {
- todo!()
+ self.inner.get_scripts()
}
fn set_scripts(&mut self, scripts: IndexMap<String, Vec<String>>) {
- todo!()
+ self.inner.set_scripts(scripts);
}
fn get_repositories(&self) -> Vec<IndexMap<String, PhpMixed>> {
- todo!()
+ self.inner.get_repositories()
}
fn set_repositories(&mut self, repositories: Vec<IndexMap<String, PhpMixed>>) {
- todo!()
+ self.inner.set_repositories(repositories);
}
fn get_license(&self) -> Vec<String> {
- todo!()
+ self.inner.get_license()
}
fn set_license(&mut self, license: Vec<String>) {
- todo!()
+ self.inner.set_license(license);
}
fn get_keywords(&self) -> Vec<String> {
- todo!()
+ self.inner.get_keywords()
}
fn set_keywords(&mut self, keywords: Vec<String>) {
- todo!()
+ self.inner.set_keywords(keywords);
}
fn get_description(&self) -> Option<&str> {
- todo!()
+ self.inner.get_description()
}
fn set_description(&mut self, description: String) {
- todo!()
+ self.inner.set_description(description);
}
fn get_homepage(&self) -> Option<&str> {
- todo!()
+ self.inner.get_homepage()
}
fn set_homepage(&mut self, homepage: String) {
- todo!()
+ self.inner.set_homepage(homepage);
}
fn get_authors(&self) -> Vec<IndexMap<String, String>> {
- todo!()
+ self.inner.get_authors()
}
fn set_authors(&mut self, authors: Vec<IndexMap<String, String>>) {
- todo!()
+ self.inner.set_authors(authors);
}
fn get_support(&self) -> IndexMap<String, String> {
- todo!()
+ self.inner.get_support()
}
fn set_support(&mut self, support: IndexMap<String, String>) {
- todo!()
+ self.inner.set_support(support);
}
fn get_funding(&self) -> Vec<IndexMap<String, PhpMixed>> {
- todo!()
+ self.inner.get_funding()
}
fn set_funding(&mut self, funding: Vec<IndexMap<String, PhpMixed>>) {
- todo!()
+ self.inner.set_funding(funding);
}
fn is_abandoned(&self) -> bool {
- todo!()
+ self.inner.is_abandoned()
}
fn get_replacement_package(&self) -> Option<&str> {
- todo!()
+ self.inner.get_replacement_package()
}
fn set_abandoned(&mut self, abandoned: PhpMixed) {
- todo!()
+ self.inner.set_abandoned(abandoned);
}
fn get_archive_name(&self) -> Option<&str> {
- todo!()
+ self.inner.get_archive_name()
}
fn set_archive_name(&mut self, name: String) {
- todo!()
+ self.inner.set_archive_name(name);
}
fn get_archive_excludes(&self) -> Vec<String> {
- todo!()
+ self.inner.get_archive_excludes()
}
fn set_archive_excludes(&mut self, excludes: Vec<String>) {
- todo!()
- }
-}
-
-impl std::fmt::Display for RootAliasPackage {
- fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- todo!()
- }
-}
-
-impl PackageInterface for RootAliasPackage {
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn get_name(&self) -> &str {
- todo!()
- }
- fn get_pretty_name(&self) -> &str {
- todo!()
- }
- fn get_names(&self, _provides: bool) -> Vec<String> {
- todo!()
- }
- fn set_id(&mut self, _id: i64) {
- todo!()
- }
- fn get_id(&self) -> i64 {
- todo!()
- }
- fn is_dev(&self) -> bool {
- todo!()
- }
- fn get_type(&self) -> &str {
- todo!()
- }
- fn get_target_dir(&self) -> Option<&str> {
- todo!()
- }
- fn get_extra(&self) -> IndexMap<String, PhpMixed> {
- todo!()
- }
- fn set_installation_source(&mut self, _type: Option<String>) {
- todo!()
- }
- fn get_installation_source(&self) -> Option<&str> {
- todo!()
- }
- fn get_source_type(&self) -> Option<&str> {
- todo!()
- }
- fn get_source_url(&self) -> Option<&str> {
- todo!()
- }
- fn get_source_urls(&self) -> Vec<String> {
- todo!()
- }
- fn get_source_reference(&self) -> Option<&str> {
- todo!()
- }
- fn get_source_mirrors(&self) -> Option<Vec<IndexMap<String, PhpMixed>>> {
- todo!()
- }
- fn set_source_mirrors(&mut self, _mirrors: Option<Vec<IndexMap<String, PhpMixed>>>) {
- todo!()
- }
- fn get_dist_type(&self) -> Option<&str> {
- todo!()
- }
- fn get_dist_url(&self) -> Option<&str> {
- todo!()
- }
- fn get_dist_urls(&self) -> Vec<String> {
- todo!()
- }
- fn get_dist_reference(&self) -> Option<&str> {
- todo!()
- }
- fn get_dist_sha1_checksum(&self) -> Option<&str> {
- todo!()
- }
- fn get_dist_mirrors(&self) -> Option<Vec<IndexMap<String, PhpMixed>>> {
- todo!()
- }
- fn set_dist_mirrors(&mut self, _mirrors: Option<Vec<IndexMap<String, PhpMixed>>>) {
- todo!()
- }
- fn get_version(&self) -> &str {
- todo!()
- }
- fn get_pretty_version(&self) -> &str {
- todo!()
- }
- fn get_full_pretty_version(&self, _truncate: bool, _display_mode: i64) -> String {
- todo!()
- }
- fn get_release_date(&self) -> Option<DateTime<Utc>> {
- todo!()
- }
- fn get_stability(&self) -> &str {
- todo!()
- }
- fn get_requires(&self) -> IndexMap<String, Link> {
- todo!()
- }
- fn get_conflicts(&self) -> IndexMap<String, Link> {
- todo!()
- }
- fn get_provides(&self) -> IndexMap<String, Link> {
- todo!()
- }
- fn get_replaces(&self) -> IndexMap<String, Link> {
- todo!()
- }
- fn get_dev_requires(&self) -> IndexMap<String, Link> {
- todo!()
- }
- fn get_suggests(&self) -> IndexMap<String, String> {
- todo!()
- }
- fn get_autoload(&self) -> IndexMap<String, PhpMixed> {
- todo!()
- }
- fn get_dev_autoload(&self) -> IndexMap<String, PhpMixed> {
- todo!()
- }
- fn get_include_paths(&self) -> Vec<String> {
- todo!()
- }
- fn get_php_ext(&self) -> Option<IndexMap<String, PhpMixed>> {
- todo!()
- }
- fn set_repository(&mut self, _repository: Box<dyn RepositoryInterface>) -> anyhow::Result<()> {
- todo!()
- }
- fn get_repository(&self) -> Option<&dyn RepositoryInterface> {
- todo!()
- }
- fn get_binaries(&self) -> Vec<String> {
- todo!()
- }
- fn get_unique_name(&self) -> String {
- todo!()
- }
- fn get_notification_url(&self) -> Option<&str> {
- todo!()
- }
- fn get_pretty_string(&self) -> String {
- todo!()
- }
- fn is_default_branch(&self) -> bool {
- todo!()
- }
- fn get_transport_options(&self) -> IndexMap<String, PhpMixed> {
- todo!()
- }
- fn set_transport_options(&mut self, _options: IndexMap<String, PhpMixed>) {
- todo!()
- }
- fn set_source_reference(&mut self, _reference: Option<String>) {
- todo!()
- }
- fn set_dist_url(&mut self, _url: Option<String>) {
- todo!()
- }
- fn set_dist_type(&mut self, _type: Option<String>) {
- todo!()
- }
- fn set_dist_reference(&mut self, _reference: Option<String>) {
- todo!()
- }
- fn set_source_dist_references(&mut self, _reference: &str) {
- todo!()
+ self.inner.set_archive_excludes(excludes);
}
}
diff --git a/crates/shirabe/src/package/root_package.rs b/crates/shirabe/src/package/root_package.rs
index 7e79530..b0fdf26 100644
--- a/crates/shirabe/src/package/root_package.rs
+++ b/crates/shirabe/src/package/root_package.rs
@@ -26,9 +26,7 @@ impl RootPackage {
pub const DEFAULT_PRETTY_VERSION: &'static str = "1.0.0+no-version-set";
pub fn new(name: String, version: String, pretty_version: String) -> Self {
- // TODO(phase-b): CompletePackage::new signature is not yet pinned down
- let inner: CompletePackage = todo!();
- let _ = (name, version, pretty_version);
+ let inner = CompletePackage::new(name, version, pretty_version);
Self {
inner,
minimum_stability: "stable".to_string(),
diff --git a/crates/shirabe/src/package/root_package_interface.rs b/crates/shirabe/src/package/root_package_interface.rs
index 2370e25..5f47232 100644
--- a/crates/shirabe/src/package/root_package_interface.rs
+++ b/crates/shirabe/src/package/root_package_interface.rs
@@ -51,14 +51,6 @@ pub trait RootPackageInterface: CompletePackageInterface {
fn set_extra(&mut self, extra: IndexMap<String, PhpMixed>);
- fn clone_as_package_interface(&self) -> Box<dyn PackageInterface> {
- todo!()
- }
-
- fn clone_box(&self) -> Box<dyn RootPackageInterface> {
- todo!()
- }
-
fn as_package_interface(&self) -> &dyn PackageInterface {
todo!()
}
diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs
index 3bd0191..28b9277 100644
--- a/crates/shirabe/src/package/version/version_selector.rs
+++ b/crates/shirabe/src/package/version/version_selector.rs
@@ -16,9 +16,8 @@ use crate::filter::platform_requirement_filter::IgnoreListPlatformRequirementFil
use crate::filter::platform_requirement_filter::PlatformRequirementFilterFactory;
use crate::filter::platform_requirement_filter::PlatformRequirementFilterInterface;
use crate::io::IOInterface;
-use crate::package::AliasPackage;
use crate::package::PackageInterface;
-use crate::package::base_package::{self, BasePackage};
+use crate::package::base_package;
use crate::package::dumper::ArrayDumper;
use crate::package::loader::ArrayLoader;
use crate::package::version::VersionParser;
@@ -69,7 +68,7 @@ impl VersionSelector {
repo_set_flags: i64,
io: Option<&dyn IOInterface>,
show_warnings: shirabe_php_shim::PhpMixed,
- ) -> anyhow::Result<Option<Box<dyn PackageInterface>>> {
+ ) -> anyhow::Result<Option<crate::package::PackageInterfaceHandle>> {
if !base_package::STABILITIES.contains_key(preferred_stability) {
return Err(shirabe_php_shim::UnexpectedValueException {
message: format!(
@@ -99,8 +98,14 @@ impl VersionSelector {
let min_priority = *base_package::STABILITIES.get(preferred_stability).unwrap();
candidates.sort_by(|a, b| {
- let a_priority = a.get_stability_priority();
- let b_priority = b.get_stability_priority();
+ // BasePackage::get_stability_priority() is not forwarded by the handle; compute it
+ // directly from the stability name.
+ let a_priority = *base_package::STABILITIES
+ .get(a.get_stability().as_str())
+ .unwrap();
+ let b_priority = *base_package::STABILITIES
+ .get(b.get_stability().as_str())
+ .unwrap();
if min_priority < a_priority && b_priority < a_priority {
return std::cmp::Ordering::Greater;
@@ -112,9 +117,9 @@ impl VersionSelector {
return std::cmp::Ordering::Less;
}
- if version_compare(b.get_version(), a.get_version(), ">") {
+ if version_compare(&b.get_version(), &a.get_version(), ">") {
std::cmp::Ordering::Greater
- } else if version_compare(b.get_version(), a.get_version(), "<") {
+ } else if version_compare(&b.get_version(), &a.get_version(), "<") {
std::cmp::Ordering::Less
} else {
std::cmp::Ordering::Equal
@@ -127,11 +132,11 @@ impl VersionSelector {
.downcast_ref::<IgnoreAllPlatformRequirementFilter>()
.is_some();
- let package: Option<Box<dyn PackageInterface>>;
+ let package: Option<crate::package::PackageInterfaceHandle>;
if !self.platform_constraints.is_empty() && !is_ignore_all {
let mut already_warned_names: IndexMap<String, bool> = IndexMap::new();
let mut already_seen_names: IndexMap<String, bool> = IndexMap::new();
- let mut found_package: Option<Box<dyn PackageInterface>> = None;
+ let mut found_package: Option<crate::package::PackageInterfaceHandle> = None;
'pkgs: for pkg in candidates.iter() {
let reqs = pkg.get_requires();
@@ -171,7 +176,7 @@ impl VersionSelector {
reason = "is missing from your platform";
}
- let is_latest_version = !already_seen_names.contains_key(pkg.get_name());
+ let is_latest_version = !already_seen_names.contains_key(&pkg.get_name());
already_seen_names.insert(pkg.get_name().to_string(), true);
if let Some(io) = io {
let should_warn = match &show_warnings {
@@ -215,13 +220,13 @@ impl VersionSelector {
continue;
}
- found_package = Some(pkg.clone_box());
+ found_package = Some(pkg.clone().into());
break;
}
package = found_package;
} else {
package = if !candidates.is_empty() {
- Some(candidates.remove(0).clone_package_box())
+ Some(candidates.remove(0).into())
} else {
None
};
@@ -232,10 +237,9 @@ impl VersionSelector {
Some(p) => p,
};
- let package = if let Some(alias) = package.as_ref().as_any().downcast_ref::<AliasPackage>()
- {
+ let package = if let Some(alias) = package.as_alias() {
if alias.get_version() == VersionParser::DEFAULT_BRANCH_ALIAS {
- alias.get_alias_of().clone_package_box()
+ alias.get_alias_of().into()
} else {
package
}