diff options
Diffstat (limited to 'crates/shirabe/src/package')
| -rw-r--r-- | crates/shirabe/src/package/alias_package.rs | 24 | ||||
| -rw-r--r-- | crates/shirabe/src/package/base_package.rs | 17 | ||||
| -rw-r--r-- | crates/shirabe/src/package/complete_package.rs | 8 | ||||
| -rw-r--r-- | crates/shirabe/src/package/handle.rs | 10 | ||||
| -rw-r--r-- | crates/shirabe/src/package/package.rs | 49 | ||||
| -rw-r--r-- | crates/shirabe/src/package/package_interface.rs | 6 | ||||
| -rw-r--r-- | crates/shirabe/src/package/root_package.rs | 10 |
7 files changed, 72 insertions, 52 deletions
diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs index 997685b..69e0723 100644 --- a/crates/shirabe/src/package/alias_package.rs +++ b/crates/shirabe/src/package/alias_package.rs @@ -11,14 +11,13 @@ use crate::package::Link; use crate::package::PackageHandle; use crate::package::PackageInterface; use crate::package::version::VersionParser; -use crate::repository::RepositoryInterface; +use crate::repository::RepositoryInterfaceHandle; #[derive(Debug)] pub struct AliasPackage { id: i64, name: String, pretty_name: String, - repository: Option<Box<dyn RepositoryInterface>>, /// @var string pub(crate) version: String, @@ -64,7 +63,6 @@ impl AliasPackage { id: -1, name: alias_name.to_lowercase(), pretty_name: alias_name, - repository: None, version, pretty_version, dev, @@ -452,12 +450,12 @@ impl PackageInterface for AliasPackage { self.alias_of.get_pretty_string() } - fn set_repository(&mut self, repository: Box<dyn RepositoryInterface>) -> anyhow::Result<()> { + fn set_repository(&mut self, repository: RepositoryInterfaceHandle) -> anyhow::Result<()> { self.alias_of.set_repository(repository) } - fn get_repository(&self) -> Option<&dyn RepositoryInterface> { - todo!("AliasPackage::get_repository cannot return a borrow across the aliasOf handle") + fn get_repository(&self) -> Option<RepositoryInterfaceHandle> { + self.alias_of.get_repository() } } @@ -486,15 +484,17 @@ impl BasePackage for AliasPackage { &mut self.pretty_name } - fn repository_opt(&self) -> Option<&dyn RepositoryInterface> { - self.repository.as_deref() + fn repository_opt(&self) -> Option<RepositoryInterfaceHandle> { + // PHP `AliasPackage::getRepository()` delegates to `$this->aliasOf->getRepository()`. + self.alias_of.get_repository() } - fn set_repository_box(&mut self, repository: Box<dyn RepositoryInterface>) { - todo!() + fn set_repository_box(&mut self, repository: RepositoryInterfaceHandle) { + let _ = self.alias_of.set_repository(repository); } - fn take_repository(&mut self) -> Option<Box<dyn RepositoryInterface>> { - todo!() + fn take_repository(&mut self) -> Option<RepositoryInterfaceHandle> { + // AliasPackage holds no repository of its own; never mutate the aliased package here. + None } } diff --git a/crates/shirabe/src/package/base_package.rs b/crates/shirabe/src/package/base_package.rs index 64a5919..ca6f171 100644 --- a/crates/shirabe/src/package/base_package.rs +++ b/crates/shirabe/src/package/base_package.rs @@ -8,7 +8,7 @@ use shirabe_php_shim::{LogicException, UnexpectedValueException, preg_quote}; use crate::package::Link; use crate::package::PackageInterface; use crate::repository::PlatformRepository; -use crate::repository::RepositoryInterface; +use crate::repository::RepositoryInterfaceHandle; pub struct SupportedLinkType { pub description: &'static str, @@ -79,15 +79,9 @@ pub trait BasePackage: PackageInterface + std::fmt::Display { fn name_mut(&mut self) -> &mut String; fn pretty_name(&self) -> &str; fn pretty_name_mut(&mut self) -> &mut String; - fn repository_opt(&self) -> Option<&dyn RepositoryInterface>; - fn set_repository_box(&mut self, repository: Box<dyn RepositoryInterface>); - fn take_repository(&mut self) -> Option<Box<dyn RepositoryInterface>>; - - /// PHP `setRepository($this)` from the containing repository — Rust port marker until - /// the borrow story for repository-package back-references is finalized in phase B. - fn set_repository_self(&mut self) { - // TODO(phase-b): wire up a back-reference to the containing repository when needed. - } + fn repository_opt(&self) -> Option<RepositoryInterfaceHandle>; + fn set_repository_box(&mut self, repository: RepositoryInterfaceHandle); + fn take_repository(&mut self) -> Option<RepositoryInterfaceHandle>; // as_alias_package / as_complete_package_interface inherited from PackageInterface. @@ -104,8 +98,7 @@ pub trait BasePackage: PackageInterface + std::fmt::Display { fn is_platform(&self) -> bool { self.repository_opt() - .and_then(|r| r.as_any().downcast_ref::<PlatformRepository>()) - .is_some() + .map_or(false, |r| r.is::<PlatformRepository>()) } fn equals(&self, _package: &dyn PackageInterface) -> bool { diff --git a/crates/shirabe/src/package/complete_package.rs b/crates/shirabe/src/package/complete_package.rs index b0adf52..a598389 100644 --- a/crates/shirabe/src/package/complete_package.rs +++ b/crates/shirabe/src/package/complete_package.rs @@ -311,13 +311,13 @@ impl PackageInterface for CompletePackage { fn set_repository( &mut self, - repository: Box<dyn crate::repository::RepositoryInterface>, + repository: crate::repository::RepositoryInterfaceHandle, ) -> anyhow::Result<()> { - todo!() + self.inner.set_repository(repository) } - fn get_repository(&self) -> Option<&dyn crate::repository::RepositoryInterface> { - todo!() + fn get_repository(&self) -> Option<crate::repository::RepositoryInterfaceHandle> { + self.inner.get_repository() } fn get_binaries(&self) -> Vec<String> { diff --git a/crates/shirabe/src/package/handle.rs b/crates/shirabe/src/package/handle.rs index 931e196..e939c3a 100644 --- a/crates/shirabe/src/package/handle.rs +++ b/crates/shirabe/src/package/handle.rs @@ -273,11 +273,11 @@ macro_rules! delegate_package_interface_to_inner { } fn set_repository( &mut self, - repository: Box<dyn crate::repository::RepositoryInterface>, + repository: crate::repository::RepositoryInterfaceHandle, ) -> anyhow::Result<()> { self.$field.set_repository(repository) } - fn get_repository(&self) -> Option<&dyn crate::repository::RepositoryInterface> { + fn get_repository(&self) -> Option<crate::repository::RepositoryInterfaceHandle> { self.$field.get_repository() } fn get_binaries(&self) -> Vec<String> { @@ -588,7 +588,7 @@ macro_rules! impl_package_interface_handle { pub fn set_repository( &self, - repository: Box<dyn crate::repository::RepositoryInterface>, + repository: crate::repository::RepositoryInterfaceHandle, ) -> anyhow::Result<()> { self.0 .borrow_mut() @@ -596,6 +596,10 @@ macro_rules! impl_package_interface_handle { .set_repository(repository) } + pub fn get_repository(&self) -> Option<crate::repository::RepositoryInterfaceHandle> { + self.0.borrow().as_package_interface().get_repository() + } + pub fn get_binaries(&self) -> Vec<String> { self.0.borrow().as_package_interface().get_binaries() } diff --git a/crates/shirabe/src/package/package.rs b/crates/shirabe/src/package/package.rs index 92836a2..680443e 100644 --- a/crates/shirabe/src/package/package.rs +++ b/crates/shirabe/src/package/package.rs @@ -1,17 +1,20 @@ //! ref: composer/src/Composer/Package/Package.php +use std::rc::Rc; + use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use shirabe_external_packages::composer::util::ComposerMirror; -use shirabe_php_shim::{E_USER_DEPRECATED, PhpMixed, strpos, trigger_error}; +use shirabe_php_shim::{E_USER_DEPRECATED, LogicException, PhpMixed, strpos, trigger_error}; use crate::package::BasePackage; use crate::package::Link; use crate::package::PackageInterface; use crate::package::version::VersionParser; -use crate::repository::RepositoryInterface; +use crate::repository::RepositoryInterfaceHandle; +use crate::repository::RepositoryInterfaceWeakHandle; /// Mirror entry, e.g. `['url' => 'https://...', 'preferred' => true]`. #[derive(Debug, Clone)] @@ -26,7 +29,8 @@ pub struct Package { id: i64, name: String, pretty_name: String, - repository: Option<Box<dyn RepositoryInterface>>, + /// Back-reference to the owning repository. `Weak` breaks the repository -> packages cycle. + repository: Option<RepositoryInterfaceWeakHandle>, pub(crate) r#type: Option<String>, pub(crate) target_dir: Option<String>, @@ -559,16 +563,22 @@ impl BasePackage for Package { &mut self.pretty_name } - fn repository_opt(&self) -> Option<&dyn RepositoryInterface> { - self.repository.as_deref() + fn repository_opt(&self) -> Option<RepositoryInterfaceHandle> { + self.repository + .as_ref() + .and_then(|w| w.upgrade()) + .map(RepositoryInterfaceHandle::from_rc) } - fn set_repository_box(&mut self, repository: Box<dyn RepositoryInterface>) { - todo!() + fn set_repository_box(&mut self, repository: RepositoryInterfaceHandle) { + self.repository = Some(repository.downgrade()); } - fn take_repository(&mut self) -> Option<Box<dyn RepositoryInterface>> { - todo!() + fn take_repository(&mut self) -> Option<RepositoryInterfaceHandle> { + self.repository + .take() + .and_then(|w| w.upgrade()) + .map(RepositoryInterfaceHandle::from_rc) } } @@ -696,11 +706,24 @@ impl PackageInterface for Package { fn get_php_ext(&self) -> Option<IndexMap<String, PhpMixed>> { todo!() } - fn set_repository(&mut self, _repository: Box<dyn RepositoryInterface>) -> anyhow::Result<()> { - todo!() + fn set_repository(&mut self, repository: RepositoryInterfaceHandle) -> anyhow::Result<()> { + if let Some(existing) = self.repository.as_ref().and_then(|w| w.upgrade()) { + if !Rc::ptr_eq(&existing, repository.as_rc()) { + return Err(LogicException { + message: "A package can only be added to one repository".to_string(), + code: 0, + } + .into()); + } + } + self.repository = Some(repository.downgrade()); + Ok(()) } - fn get_repository(&self) -> Option<&dyn RepositoryInterface> { - todo!() + fn get_repository(&self) -> Option<RepositoryInterfaceHandle> { + self.repository + .as_ref() + .and_then(|w| w.upgrade()) + .map(RepositoryInterfaceHandle::from_rc) } fn get_binaries(&self) -> Vec<String> { todo!() diff --git a/crates/shirabe/src/package/package_interface.rs b/crates/shirabe/src/package/package_interface.rs index 0ec6e26..92729a4 100644 --- a/crates/shirabe/src/package/package_interface.rs +++ b/crates/shirabe/src/package/package_interface.rs @@ -5,7 +5,7 @@ use indexmap::IndexMap; use shirabe_php_shim::PhpMixed; use crate::package::Link; -use crate::repository::RepositoryInterface; +use crate::repository::RepositoryInterfaceHandle; /// Defines the essential information a package has that is used during solving/installation /// @@ -244,10 +244,10 @@ pub trait PackageInterface: std::fmt::Display + std::fmt::Debug { fn get_php_ext(&self) -> Option<IndexMap<String, PhpMixed>>; /// Stores a reference to the repository that owns the package - fn set_repository(&mut self, repository: Box<dyn RepositoryInterface>) -> anyhow::Result<()>; + fn set_repository(&mut self, repository: RepositoryInterfaceHandle) -> anyhow::Result<()>; /// Returns a reference to the repository that owns the package - fn get_repository(&self) -> Option<&dyn RepositoryInterface>; + fn get_repository(&self) -> Option<RepositoryInterfaceHandle>; /// Returns the package binaries /// diff --git a/crates/shirabe/src/package/root_package.rs b/crates/shirabe/src/package/root_package.rs index df676ff..028f43b 100644 --- a/crates/shirabe/src/package/root_package.rs +++ b/crates/shirabe/src/package/root_package.rs @@ -9,7 +9,7 @@ use crate::package::CompletePackageInterface; use crate::package::Link; use crate::package::PackageInterface; use crate::package::RootPackageInterface; -use crate::repository::RepositoryInterface; +use crate::repository::RepositoryInterfaceHandle; #[derive(Debug)] pub struct RootPackage { @@ -351,11 +351,11 @@ impl PackageInterface for RootPackage { fn get_php_ext(&self) -> Option<IndexMap<String, PhpMixed>> { todo!() } - fn set_repository(&mut self, _repository: Box<dyn RepositoryInterface>) -> anyhow::Result<()> { - todo!() + fn set_repository(&mut self, repository: RepositoryInterfaceHandle) -> anyhow::Result<()> { + self.inner.set_repository(repository) } - fn get_repository(&self) -> Option<&dyn RepositoryInterface> { - todo!() + fn get_repository(&self) -> Option<RepositoryInterfaceHandle> { + self.inner.get_repository() } fn get_binaries(&self) -> Vec<String> { todo!() |
