diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-25 00:58:20 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-25 00:58:36 +0900 |
| commit | 1921f173ea219cb4b25847294d2d3fa465550fbb (patch) | |
| tree | 0d30486a2cb9a0c106e5d5827be3f655c60cd871 /crates/shirabe/src/dependency_resolver/lock_transaction.rs | |
| parent | dbdecaf5a1c54a876b7ee0153d58dd39b1080f97 (diff) | |
| download | php-shirabe-1921f173ea219cb4b25847294d2d3fa465550fbb.tar.gz php-shirabe-1921f173ea219cb4b25847294d2d3fa465550fbb.tar.zst php-shirabe-1921f173ea219cb4b25847294d2d3fa465550fbb.zip | |
refactor(package): introduce Rc<RefCell<_>> handles for packages
PHP packages have reference semantics, so introduce shared-ownership
handles over an AnyPackage enum (PackageInterfaceHandle and friends)
and replace Box<dyn PackageInterface> throughout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/dependency_resolver/lock_transaction.rs')
| -rw-r--r-- | crates/shirabe/src/dependency_resolver/lock_transaction.rs | 78 |
1 files changed, 33 insertions, 45 deletions
diff --git a/crates/shirabe/src/dependency_resolver/lock_transaction.rs b/crates/shirabe/src/dependency_resolver/lock_transaction.rs index 14900d1..09d4571 100644 --- a/crates/shirabe/src/dependency_resolver/lock_transaction.rs +++ b/crates/shirabe/src/dependency_resolver/lock_transaction.rs @@ -1,34 +1,30 @@ //! ref: composer/src/Composer/DependencyResolver/LockTransaction.php -use std::any::Any; - use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use crate::dependency_resolver::Decisions; use crate::dependency_resolver::Pool; use crate::dependency_resolver::Transaction; -use crate::package::AliasPackage; -use crate::package::Package; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; #[derive(Debug)] pub struct LockTransaction { inner: Transaction, /// packages in current lock file, platform repo or otherwise present /// Indexed by spl_object_hash - pub(crate) present_map: IndexMap<String, Box<dyn PackageInterface>>, + pub(crate) present_map: IndexMap<String, PackageInterfaceHandle>, /// Packages which cannot be mapped, platform repo, root package, other fixed repos /// Indexed by package id - pub(crate) unlockable_map: IndexMap<i64, Box<dyn PackageInterface>>, - pub(crate) result_packages: IndexMap<String, Vec<Box<dyn PackageInterface>>>, + pub(crate) unlockable_map: IndexMap<i64, PackageInterfaceHandle>, + pub(crate) result_packages: IndexMap<String, Vec<PackageInterfaceHandle>>, } impl LockTransaction { pub fn new( pool: &Pool, - present_map: IndexMap<String, Box<dyn PackageInterface>>, - unlockable_map: IndexMap<i64, Box<dyn PackageInterface>>, + present_map: IndexMap<String, PackageInterfaceHandle>, + unlockable_map: IndexMap<i64, PackageInterfaceHandle>, decisions: &Decisions, ) -> Self { let mut this = Self { @@ -38,22 +34,18 @@ impl LockTransaction { result_packages: IndexMap::new(), }; this.set_result_packages(pool, decisions); - let all: Vec<Box<dyn PackageInterface>> = this + let all: Vec<PackageInterfaceHandle> = this .result_packages .get("all") - .map(|v| v.iter().map(|p| p.clone_package_box()).collect()) + .map(|v| v.iter().cloned().collect()) .unwrap_or_default(); - let present: Vec<Box<dyn PackageInterface>> = this - .present_map - .values() - .map(|p| p.clone_package_box()) - .collect(); + let present: Vec<PackageInterfaceHandle> = this.present_map.values().cloned().collect(); this.inner = Transaction::new(present, all); this } pub fn set_result_packages(&mut self, pool: &Pool, decisions: &Decisions) { - let mut result_packages: IndexMap<String, Vec<Box<dyn PackageInterface>>> = IndexMap::new(); + let mut result_packages: IndexMap<String, Vec<PackageInterfaceHandle>> = IndexMap::new(); result_packages.insert("all".to_string(), vec![]); result_packages.insert("non-dev".to_string(), vec![]); result_packages.insert("dev".to_string(), vec![]); @@ -67,12 +59,12 @@ impl LockTransaction { result_packages .get_mut("all") .unwrap() - .push(package.clone_box()); + .push(package.clone().into()); if !self.unlockable_map.contains_key(&package.get_id()) { result_packages .get_mut("non-dev") .unwrap() - .push(package.clone_box()); + .push(package.clone().into()); } } } @@ -110,7 +102,7 @@ impl LockTransaction { &self, dev_mode: bool, update_mirrors: bool, - ) -> Vec<Box<dyn PackageInterface>> { + ) -> Vec<PackageInterfaceHandle> { let key = if dev_mode { "dev" } else { "non-dev" }; let mut packages = vec![]; @@ -120,26 +112,22 @@ impl LockTransaction { .map(|v| v.as_slice()) .unwrap_or_default(); for package in source { - if package.as_any().downcast_ref::<AliasPackage>().is_some() { + if package.as_alias().is_some() { continue; } - if update_mirrors - && !self - .present_map - .contains_key(&shirabe_php_shim::spl_object_hash(package.as_ref())) - { - let updated = self.update_mirror_and_urls(package.as_ref()); + if update_mirrors && !self.present_map.contains_key(&package.ptr_id().to_string()) { + let updated = self.update_mirror_and_urls(package); packages.push(updated); } else { - packages.push(package.clone_package_box()); + packages.push(package.clone()); } } packages } - fn update_mirror_and_urls(&self, package: &dyn PackageInterface) -> Box<dyn PackageInterface> { + fn update_mirror_and_urls(&self, package: &PackageInterfaceHandle) -> PackageInterfaceHandle { for present_package in self.present_map.values() { if package.get_name() != present_package.get_name() { continue; @@ -157,38 +145,38 @@ impl LockTransaction { continue; } - if let Some(concrete_pkg) = present_package.as_any().downcast_ref::<Package>() { - // TODO(phase-b): set_source_url/set_source_mirrors expect &mut and owned types; - // present_package is &Box<dyn PackageInterface> (immutable). Revisit ownership. + if let Some(concrete_pkg) = present_package.as_package() { + // TODO(phase-c): mirror the source url/mirrors of the present package onto it via + // its handle setters once the per-field copy semantics are reviewed. let _ = concrete_pkg; - let _ = package.get_source_url().map(|s| s.to_string()); + let _ = package.get_source_url(); let _ = package.get_source_mirrors(); } if present_package.get_dist_type() != package.get_dist_type() { - return present_package.clone_package_box(); + return present_package.clone(); } if package.get_dist_url().is_some() && present_package.get_dist_reference().is_some() - && Preg::is_match(r"{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com|(?:www\.)?gitlab\.com)/}i", package.get_dist_url().unwrap()).unwrap_or(false) + && Preg::is_match(r"{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com|(?:www\.)?gitlab\.com)/}i", &package.get_dist_url().unwrap()).unwrap_or(false) { let new_dist_url = Preg::replace( r"{(?<=/|sha=)[a-f0-9]{40}(?=/|$)}i", - present_package.get_dist_reference().unwrap(), - package.get_dist_url().unwrap(), + &present_package.get_dist_reference().unwrap(), + &package.get_dist_url().unwrap(), ) - .unwrap_or_else(|_| package.get_dist_url().unwrap().to_string()); - // TODO(phase-b): set_dist_url requires &mut PackageInterface; revisit ownership. + .unwrap_or_else(|_| package.get_dist_url().unwrap()); + // TODO(phase-c): apply new_dist_url onto present_package via its handle setter. let _ = new_dist_url; } - // TODO(phase-b): set_dist_mirrors requires &mut PackageInterface; revisit ownership. + // TODO(phase-c): apply dist mirrors onto present_package via its handle setter. let _ = package.get_dist_mirrors(); - return present_package.clone_package_box(); + return present_package.clone(); } - package.clone_package_box() + package.clone() } pub fn get_aliases( @@ -200,11 +188,11 @@ impl LockTransaction { if let Some(all_packages) = self.result_packages.get("all") { for package in all_packages { - if package.as_any().downcast_ref::<AliasPackage>().is_some() { + if package.as_alias().is_some() { let mut i = 0; while i < remaining_aliases.len() { if remaining_aliases[i].get("package").map(|s| s.as_str()) - == Some(package.get_name()) + == Some(package.get_name().as_str()) { used_aliases.push(remaining_aliases.remove(i)); } else { |
