aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/composer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/composer.rs')
-rw-r--r--crates/shirabe/src/composer.rs723
1 files changed, 354 insertions, 369 deletions
diff --git a/crates/shirabe/src/composer.rs b/crates/shirabe/src/composer.rs
index fe700cf..6a2337a 100644
--- a/crates/shirabe/src/composer.rs
+++ b/crates/shirabe/src/composer.rs
@@ -31,255 +31,315 @@ pub fn get_version() -> String {
VERSION.to_string()
}
+/// Interface for \Composer\PartialComposer. Implemented by every composer handle, since both a
+/// partial and a full composer expose these common members.
+pub trait PartialComposer {
+ fn set_package(&self, package: RootPackageInterfaceHandle);
+ fn get_package(&self) -> RootPackageInterfaceHandle;
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>);
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>>;
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>);
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>>;
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>);
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>>;
+ fn set_installation_manager(
+ &self,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
+ );
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>>;
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
+ );
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>>;
+ fn is_global(&self) -> bool;
+ fn set_global(&self);
+}
+
+/// Interface for \Composer\Composer (`extends PartialComposer`). Implemented only by fully-loaded
+/// composer handles, which additionally expose the full-only members below.
+pub trait Composer: PartialComposer {
+ fn set_locker(&self, locker: std::rc::Rc<std::cell::RefCell<Locker>>);
+ fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>>;
+ fn set_download_manager(&self, manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>);
+ fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>>;
+ // TODO(plugin): set_plugin_manager is part of the plugin API
+ fn set_plugin_manager(&self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>);
+ // TODO(plugin): get_plugin_manager is part of the plugin API
+ fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>>;
+ fn set_autoload_generator(
+ &self,
+ autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
+ );
+ fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>;
+ fn set_archive_manager(&self, manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>);
+ fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>>;
+}
+
/// Internal data type corresponding to \Composer\PartialComposer.
#[derive(Debug, Default)]
-pub struct PartialComposer {
- global: bool,
- package: Option<RootPackageInterfaceHandle>,
- r#loop: Option<std::rc::Rc<std::cell::RefCell<Loop>>>,
- repository_manager: Option<std::rc::Rc<std::cell::RefCell<RepositoryManager>>>,
- installation_manager: Option<std::rc::Rc<std::cell::RefCell<InstallationManager>>>,
- config: Option<std::rc::Rc<std::cell::RefCell<Config>>>,
- event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
+pub(crate) struct InnerPartialComposer {
+ pub(crate) global: bool,
+ pub(crate) package: Option<RootPackageInterfaceHandle>,
+ pub(crate) r#loop: Option<std::rc::Rc<std::cell::RefCell<Loop>>>,
+ pub(crate) repository_manager: Option<std::rc::Rc<std::cell::RefCell<RepositoryManager>>>,
+ pub(crate) installation_manager: Option<std::rc::Rc<std::cell::RefCell<InstallationManager>>>,
+ pub(crate) config: Option<std::rc::Rc<std::cell::RefCell<Config>>>,
+ pub(crate) event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
}
-impl PartialComposer {
- pub fn set_package(&mut self, package: RootPackageInterfaceHandle) {
- self.package = Some(package);
- }
+/// Internal data type corresponding to \Composer\Composer.
+#[derive(Debug, Default)]
+pub(crate) struct InnerFullComposer {
+ pub(crate) partial: InnerPartialComposer,
+ pub(crate) locker: Option<std::rc::Rc<std::cell::RefCell<Locker>>>,
+ pub(crate) download_manager: Option<std::rc::Rc<std::cell::RefCell<DownloadManager>>>,
+ // TODO(plugin): plugin_manager is part of the plugin API
+ pub(crate) plugin_manager: Option<std::rc::Rc<std::cell::RefCell<PluginManager>>>,
+ pub(crate) autoload_generator: Option<std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>>,
+ pub(crate) archive_manager: Option<std::rc::Rc<std::cell::RefCell<ArchiveManager>>>,
+}
- pub fn get_package(&self) -> &RootPackageInterfaceHandle {
- self.package.as_ref().unwrap()
- }
+/// Shared reference to a fully-loaded \Composer\Composer.
+/// Use this for parameters or fields typed as \Composer\Composer in PHP.
+#[derive(Debug, Clone)]
+pub struct FullComposerHandle(std::rc::Rc<std::cell::RefCell<InnerFullComposer>>);
- pub fn set_config(&mut self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
- self.config = Some(config);
+impl FullComposerHandle {
+ pub(crate) fn from_rc(rc: std::rc::Rc<std::cell::RefCell<InnerFullComposer>>) -> Self {
+ Self(rc)
}
- pub fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
- self.config.as_ref().unwrap().clone()
+ pub(crate) fn as_rc(&self) -> &std::rc::Rc<std::cell::RefCell<InnerFullComposer>> {
+ &self.0
}
- pub fn set_loop(&mut self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
- self.r#loop = Some(r#loop);
+ pub fn downgrade(&self) -> FullComposerWeakHandle {
+ FullComposerWeakHandle(std::rc::Rc::downgrade(&self.0))
}
+}
- pub fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
- self.r#loop.as_ref().unwrap().clone()
+impl PartialComposer for FullComposerHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
+ self.0.borrow_mut().partial.package = Some(package);
}
-
- pub fn set_repository_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>,
- ) {
- self.repository_manager = Some(manager);
+ fn get_package(&self) -> RootPackageInterfaceHandle {
+ self.0.borrow().partial.package.as_ref().unwrap().clone()
}
-
- pub fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
- self.repository_manager.as_ref().unwrap().clone()
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
+ self.0.borrow_mut().partial.config = Some(config);
}
-
- pub fn set_installation_manager(
- &mut self,
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
+ self.0.borrow().partial.config.as_ref().unwrap().clone()
+ }
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
+ self.0.borrow_mut().partial.r#loop = Some(r#loop);
+ }
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
+ self.0.borrow().partial.r#loop.as_ref().unwrap().clone()
+ }
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
+ self.0.borrow_mut().partial.repository_manager = Some(manager);
+ }
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
+ self.0
+ .borrow()
+ .partial
+ .repository_manager
+ .as_ref()
+ .unwrap()
+ .clone()
+ }
+ fn set_installation_manager(
+ &self,
manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
) {
- self.installation_manager = Some(manager);
+ self.0.borrow_mut().partial.installation_manager = Some(manager);
}
-
- pub fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
- self.installation_manager.as_ref().unwrap().clone()
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
+ self.0
+ .borrow()
+ .partial
+ .installation_manager
+ .as_ref()
+ .unwrap()
+ .clone()
}
-
- pub fn set_event_dispatcher(
- &mut self,
+ fn set_event_dispatcher(
+ &self,
event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
) {
- self.event_dispatcher = Some(event_dispatcher);
+ self.0.borrow_mut().partial.event_dispatcher = Some(event_dispatcher);
}
-
- pub fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
- self.event_dispatcher.as_ref().unwrap().clone()
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
+ self.0
+ .borrow()
+ .partial
+ .event_dispatcher
+ .as_ref()
+ .unwrap()
+ .clone()
}
-
- pub fn is_global(&self) -> bool {
- self.global
+ fn is_global(&self) -> bool {
+ self.0.borrow().partial.global
}
-
- pub fn set_global(&mut self) {
- self.global = true;
+ fn set_global(&self) {
+ self.0.borrow_mut().partial.global = true;
}
}
-/// Internal data type corresponding to \Composer\Composer.
-#[derive(Debug)]
-pub struct Composer {
- partial: PartialComposer,
- locker: Option<std::rc::Rc<std::cell::RefCell<Locker>>>,
- download_manager: Option<std::rc::Rc<std::cell::RefCell<DownloadManager>>>,
- // TODO(plugin): plugin_manager is part of the plugin API
- plugin_manager: Option<std::rc::Rc<std::cell::RefCell<PluginManager>>>,
- autoload_generator: Option<std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>>,
- archive_manager: Option<std::rc::Rc<std::cell::RefCell<ArchiveManager>>>,
-}
-
-impl Composer {
- pub fn new() -> Self {
- Self {
- partial: PartialComposer::default(),
- locker: None,
- download_manager: None,
- plugin_manager: None,
- autoload_generator: None,
- archive_manager: None,
- }
+impl Composer for FullComposerHandle {
+ fn set_locker(&self, locker: std::rc::Rc<std::cell::RefCell<Locker>>) {
+ self.0.borrow_mut().locker = Some(locker);
}
-
- pub fn set_locker(&mut self, locker: std::rc::Rc<std::cell::RefCell<Locker>>) {
- self.locker = Some(locker);
+ fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>> {
+ self.0.borrow().locker.as_ref().unwrap().clone()
}
-
- pub fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>> {
- self.locker.as_ref().unwrap().clone()
+ fn set_download_manager(&self, manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>) {
+ self.0.borrow_mut().download_manager = Some(manager);
}
-
- pub fn set_download_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>,
- ) {
- self.download_manager = Some(manager);
+ fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>> {
+ self.0.borrow().download_manager.as_ref().unwrap().clone()
}
-
- pub fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>> {
- self.download_manager.as_ref().unwrap().clone()
+ fn set_plugin_manager(&self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>) {
+ self.0.borrow_mut().plugin_manager = Some(manager);
}
-
- pub fn set_archive_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>,
+ fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>> {
+ self.0.borrow().plugin_manager.as_ref().unwrap().clone()
+ }
+ fn set_autoload_generator(
+ &self,
+ autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
) {
- self.archive_manager = Some(manager);
+ self.0.borrow_mut().autoload_generator = Some(autoload_generator);
}
-
- pub fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>> {
- self.archive_manager.as_ref().unwrap().clone()
+ fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>> {
+ self.0.borrow().autoload_generator.as_ref().unwrap().clone()
}
-
- // TODO(plugin): set_plugin_manager is part of the plugin API
- pub fn set_plugin_manager(&mut self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>) {
- self.plugin_manager = Some(manager);
+ fn set_archive_manager(&self, manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>) {
+ self.0.borrow_mut().archive_manager = Some(manager);
}
-
- // TODO(plugin): get_plugin_manager is part of the plugin API
- pub fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>> {
- self.plugin_manager.as_ref().unwrap().clone()
+ fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>> {
+ self.0.borrow().archive_manager.as_ref().unwrap().clone()
}
+}
- pub fn set_autoload_generator(
- &mut self,
- autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
- ) {
- self.autoload_generator = Some(autoload_generator);
- }
+/// Shared weak reference to a fully-loaded \Composer\Composer.
+#[derive(Debug, Clone)]
+pub struct FullComposerWeakHandle(std::rc::Weak<std::cell::RefCell<InnerFullComposer>>);
- pub fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>> {
- self.autoload_generator.as_ref().unwrap().clone()
+impl FullComposerWeakHandle {
+ pub(crate) fn from_weak(weak: std::rc::Weak<std::cell::RefCell<InnerFullComposer>>) -> Self {
+ Self(weak)
}
- pub fn as_partial(&self) -> &PartialComposer {
- &self.partial
+ pub fn upgrade(&self) -> Option<FullComposerHandle> {
+ self.0.upgrade().map(FullComposerHandle)
}
- pub fn as_partial_mut(&mut self) -> &mut PartialComposer {
- &mut self.partial
+ fn upgraded(&self) -> FullComposerHandle {
+ self.upgrade()
+ .expect("Composer has been dropped before its weak reference")
}
+}
- pub fn set_package(&mut self, package: RootPackageInterfaceHandle) {
- self.partial.set_package(package);
+impl PartialComposer for FullComposerWeakHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
+ self.upgraded().set_package(package);
}
-
- pub fn get_package(&self) -> &RootPackageInterfaceHandle {
- self.partial.get_package()
+ fn get_package(&self) -> RootPackageInterfaceHandle {
+ self.upgraded().get_package()
}
-
- pub fn set_config(&mut self, config: std::rc::Rc<std::cell::RefCell<crate::config::Config>>) {
- self.partial.set_config(config);
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
+ self.upgraded().set_config(config);
}
-
- pub fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<crate::config::Config>> {
- self.partial.get_config()
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
+ self.upgraded().get_config()
}
-
- pub fn set_loop(&mut self, r#loop: std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>>) {
- self.partial.set_loop(r#loop);
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
+ self.upgraded().set_loop(r#loop);
}
-
- pub fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>> {
- self.partial.get_loop()
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
+ self.upgraded().get_loop()
}
-
- pub fn set_repository_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>>,
- ) {
- self.partial.set_repository_manager(manager);
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
+ self.upgraded().set_repository_manager(manager);
}
-
- pub fn get_repository_manager(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>> {
- self.partial.get_repository_manager()
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
+ self.upgraded().get_repository_manager()
}
-
- pub fn set_installation_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>>,
+ fn set_installation_manager(
+ &self,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
) {
- self.partial.set_installation_manager(manager);
+ self.upgraded().set_installation_manager(manager);
}
-
- pub fn get_installation_manager(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>> {
- self.partial.get_installation_manager()
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
+ self.upgraded().get_installation_manager()
}
-
- pub fn set_event_dispatcher(
- &mut self,
- dispatcher: std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>>,
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
) {
- self.partial.set_event_dispatcher(dispatcher);
+ self.upgraded().set_event_dispatcher(event_dispatcher);
+ }
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
+ self.upgraded().get_event_dispatcher()
+ }
+ fn is_global(&self) -> bool {
+ self.upgraded().is_global()
+ }
+ fn set_global(&self) {
+ self.upgraded().set_global();
}
+}
- pub fn get_event_dispatcher(
+impl Composer for FullComposerWeakHandle {
+ fn set_locker(&self, locker: std::rc::Rc<std::cell::RefCell<Locker>>) {
+ self.upgraded().set_locker(locker);
+ }
+ fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>> {
+ self.upgraded().get_locker()
+ }
+ fn set_download_manager(&self, manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>) {
+ self.upgraded().set_download_manager(manager);
+ }
+ fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>> {
+ self.upgraded().get_download_manager()
+ }
+ fn set_plugin_manager(&self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>) {
+ self.upgraded().set_plugin_manager(manager);
+ }
+ fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>> {
+ self.upgraded().get_plugin_manager()
+ }
+ fn set_autoload_generator(
&self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>> {
- self.partial.get_event_dispatcher()
+ autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
+ ) {
+ self.upgraded().set_autoload_generator(autoload_generator);
}
-
- pub fn is_global(&self) -> bool {
- self.partial.is_global()
+ fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>> {
+ self.upgraded().get_autoload_generator()
}
-
- pub fn set_global(&mut self) {
- self.partial.set_global();
+ fn set_archive_manager(&self, manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>) {
+ self.upgraded().set_archive_manager(manager);
+ }
+ fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>> {
+ self.upgraded().get_archive_manager()
}
}
-#[derive(Debug)]
-pub enum PartialOrFullComposer {
- Full(Composer),
- Partial(PartialComposer),
+/// Shared reference to a \Composer\PartialComposer that may at runtime be either a partial composer
+/// or a full \Composer\Composer. Use this for parameters or fields typed as \Composer\PartialComposer
+/// in PHP; downcast with [`AnyComposerHandle::as_full`] (`$composer instanceof Composer`).
+#[derive(Debug, Clone)]
+pub enum AnyComposerHandle {
+ Partial(std::rc::Rc<std::cell::RefCell<InnerPartialComposer>>),
+ Full(FullComposerHandle),
}
-impl PartialOrFullComposer {
- pub fn new_full() -> Self {
- Self::Full(Composer::new())
- }
-
- pub fn new_partial() -> Self {
- Self::Partial(PartialComposer::default())
- }
-
+impl AnyComposerHandle {
pub fn is_full(&self) -> bool {
matches!(self, Self::Full(_))
}
@@ -288,274 +348,199 @@ impl PartialOrFullComposer {
matches!(self, Self::Partial(_))
}
- pub fn as_full(&self) -> Option<&Composer> {
+ /// Downcast to a full Composer handle. PHP `$composer instanceof Composer`.
+ pub fn as_full(&self) -> Option<FullComposerHandle> {
match self {
- Self::Full(full) => Some(full),
+ Self::Full(full) => Some(full.clone()),
Self::Partial(_) => None,
}
}
- pub fn as_full_mut(&mut self) -> Option<&mut Composer> {
+ pub fn downgrade(&self) -> AnyComposerWeakHandle {
match self {
- Self::Full(full) => Some(full),
- Self::Partial(_) => None,
+ Self::Partial(rc) => AnyComposerWeakHandle::Partial(std::rc::Rc::downgrade(rc)),
+ Self::Full(full) => AnyComposerWeakHandle::Full(full.downgrade()),
}
}
+}
- pub fn as_partial(&self) -> &PartialComposer {
- match self {
- Self::Full(full) => full.as_partial(),
- Self::Partial(partial) => partial,
- }
+impl From<FullComposerHandle> for AnyComposerHandle {
+ fn from(h: FullComposerHandle) -> Self {
+ Self::Full(h)
}
+}
- pub fn as_partial_mut(&mut self) -> &mut PartialComposer {
+impl PartialComposer for AnyComposerHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
match self {
- Self::Full(full) => full.as_partial_mut(),
- Self::Partial(partial) => partial,
+ Self::Partial(rc) => rc.borrow_mut().package = Some(package),
+ Self::Full(f) => f.set_package(package),
}
}
-
- pub fn set_package(&mut self, package: RootPackageInterfaceHandle) {
+ fn get_package(&self) -> RootPackageInterfaceHandle {
match self {
- Self::Full(full) => full.set_package(package),
- Self::Partial(partial) => partial.set_package(package),
+ Self::Partial(rc) => rc.borrow().package.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_package(),
}
}
-
- pub fn get_package(&self) -> &RootPackageInterfaceHandle {
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
match self {
- Self::Full(full) => full.get_package(),
- Self::Partial(partial) => partial.get_package(),
+ Self::Partial(rc) => rc.borrow_mut().config = Some(config),
+ Self::Full(f) => f.set_config(config),
}
}
-
- pub fn set_config(&mut self, config: std::rc::Rc<std::cell::RefCell<crate::config::Config>>) {
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
match self {
- Self::Full(full) => full.set_config(config),
- Self::Partial(partial) => partial.set_config(config),
+ Self::Partial(rc) => rc.borrow().config.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_config(),
}
}
-
- pub fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<crate::config::Config>> {
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
match self {
- Self::Full(full) => full.get_config(),
- Self::Partial(partial) => partial.get_config(),
+ Self::Partial(rc) => rc.borrow_mut().r#loop = Some(r#loop),
+ Self::Full(f) => f.set_loop(r#loop),
}
}
-
- pub fn set_loop(&mut self, r#loop: std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>>) {
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
match self {
- Self::Full(full) => full.set_loop(r#loop),
- Self::Partial(partial) => partial.set_loop(r#loop),
+ Self::Partial(rc) => rc.borrow().r#loop.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_loop(),
}
}
-
- pub fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>> {
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
match self {
- Self::Full(full) => full.get_loop(),
- Self::Partial(partial) => partial.get_loop(),
+ Self::Partial(rc) => rc.borrow_mut().repository_manager = Some(manager),
+ Self::Full(f) => f.set_repository_manager(manager),
}
}
-
- pub fn set_repository_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>>,
- ) {
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
match self {
- Self::Full(full) => full.set_repository_manager(manager),
- Self::Partial(partial) => partial.set_repository_manager(manager),
+ Self::Partial(rc) => rc.borrow().repository_manager.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_repository_manager(),
}
}
-
- pub fn get_repository_manager(
+ fn set_installation_manager(
&self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>> {
- match self {
- Self::Full(full) => full.get_repository_manager(),
- Self::Partial(partial) => partial.get_repository_manager(),
- }
- }
-
- pub fn set_installation_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>>,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
) {
match self {
- Self::Full(full) => full.set_installation_manager(manager),
- Self::Partial(partial) => partial.set_installation_manager(manager),
+ Self::Partial(rc) => rc.borrow_mut().installation_manager = Some(manager),
+ Self::Full(f) => f.set_installation_manager(manager),
}
}
-
- pub fn get_installation_manager(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>> {
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
match self {
- Self::Full(full) => full.get_installation_manager(),
- Self::Partial(partial) => partial.get_installation_manager(),
+ Self::Partial(rc) => rc.borrow().installation_manager.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_installation_manager(),
}
}
-
- pub fn set_event_dispatcher(
- &mut self,
- dispatcher: std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>>,
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
) {
match self {
- Self::Full(full) => full.set_event_dispatcher(dispatcher),
- Self::Partial(partial) => partial.set_event_dispatcher(dispatcher),
+ Self::Partial(rc) => rc.borrow_mut().event_dispatcher = Some(event_dispatcher),
+ Self::Full(f) => f.set_event_dispatcher(event_dispatcher),
}
}
-
- pub fn get_event_dispatcher(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>> {
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
match self {
- Self::Full(full) => full.get_event_dispatcher(),
- Self::Partial(partial) => partial.get_event_dispatcher(),
+ Self::Partial(rc) => rc.borrow().event_dispatcher.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_event_dispatcher(),
}
}
-
- pub fn is_global(&self) -> bool {
+ fn is_global(&self) -> bool {
match self {
- Self::Full(full) => full.is_global(),
- Self::Partial(partial) => partial.is_global(),
+ Self::Partial(rc) => rc.borrow().global,
+ Self::Full(f) => f.is_global(),
}
}
-
- pub fn set_global(&mut self) {
+ fn set_global(&self) {
match self {
- Self::Full(full) => full.set_global(),
- Self::Partial(partial) => partial.set_global(),
+ Self::Partial(rc) => rc.borrow_mut().global = true,
+ Self::Full(f) => f.set_global(),
}
}
}
-/// Shared reference to \Composer\PartialComposer or \Composer\Composer.
-/// Use this for parameters or fields typed as \Composer\PartialComposer in PHP.
+/// Shared weak reference to a \Composer\PartialComposer that may at runtime be either partial or full.
#[derive(Debug, Clone)]
-pub struct PartialComposerHandle(std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl PartialComposerHandle {
- pub fn borrow_partial(&self) -> std::cell::Ref<'_, PartialComposer> {
- std::cell::Ref::map(self.0.borrow(), |c| c.as_partial())
- }
-
- pub fn borrow_partial_mut(&self) -> std::cell::RefMut<'_, PartialComposer> {
- std::cell::RefMut::map(self.0.borrow_mut(), |c| c.as_partial_mut())
- }
-
- pub fn is_full(&self) -> bool {
- self.0.borrow().is_full()
- }
+pub enum AnyComposerWeakHandle {
+ Partial(std::rc::Weak<std::cell::RefCell<InnerPartialComposer>>),
+ Full(FullComposerWeakHandle),
+}
- /// Downcast to a full Composer handle. PHP `$composer instanceof Composer`.
- pub fn as_full(&self) -> Option<ComposerHandle> {
- if self.0.borrow().is_full() {
- Some(ComposerHandle::from_rc_unchecked(self.0.clone()))
- } else {
- None
+impl AnyComposerWeakHandle {
+ pub fn upgrade(&self) -> Option<AnyComposerHandle> {
+ match self {
+ Self::Partial(p) => p.upgrade().map(AnyComposerHandle::Partial),
+ Self::Full(f) => f.upgrade().map(AnyComposerHandle::Full),
}
}
- pub fn downgrade(&self) -> PartialComposerWeakHandle {
- PartialComposerWeakHandle(std::rc::Rc::downgrade(&self.0))
+ fn upgraded(&self) -> AnyComposerHandle {
+ self.upgrade()
+ .expect("PartialComposer has been dropped before its weak reference")
}
+}
- pub fn from_rc(rc: std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(rc)
+impl PartialComposer for AnyComposerWeakHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
+ self.upgraded().set_package(package);
}
-
- pub fn as_rc(&self) -> &std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>> {
- &self.0
+ fn get_package(&self) -> RootPackageInterfaceHandle {
+ self.upgraded().get_package()
}
-}
-
-/// Shared weak reference to \Composer\PartialComposer or \Composer\Composer.
-#[derive(Debug, Clone)]
-pub struct PartialComposerWeakHandle(std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl PartialComposerWeakHandle {
- pub fn upgrade(&self) -> Option<PartialComposerHandle> {
- self.0.upgrade().map(PartialComposerHandle)
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
+ self.upgraded().set_config(config);
}
-
- pub fn from_weak(weak: std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(weak)
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
+ self.upgraded().get_config()
}
-}
-
-/// Shared reference to \Composer\Composer.
-/// Use this for parameters or fields typed as \Composer\Composer in PHP.
-#[derive(Debug, Clone)]
-pub struct ComposerHandle(std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl ComposerHandle {
- pub fn borrow(&self) -> std::cell::Ref<'_, Composer> {
- std::cell::Ref::map(self.0.borrow(), |c| {
- c.as_full()
- .expect("Composer handle invariant: inner is Full")
- })
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
+ self.upgraded().set_loop(r#loop);
}
-
- pub fn borrow_mut(&self) -> std::cell::RefMut<'_, Composer> {
- std::cell::RefMut::map(self.0.borrow_mut(), |c| {
- c.as_full_mut()
- .expect("Composer handle invariant: inner is Full")
- })
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
+ self.upgraded().get_loop()
}
-
- pub fn upcast(&self) -> PartialComposerHandle {
- PartialComposerHandle::from_rc(self.0.clone())
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
+ self.upgraded().set_repository_manager(manager);
}
-
- pub fn downgrade(&self) -> ComposerWeakHandle {
- ComposerWeakHandle(std::rc::Rc::downgrade(&self.0))
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
+ self.upgraded().get_repository_manager()
}
-
- pub fn from_rc_unchecked(rc: std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(rc)
+ fn set_installation_manager(
+ &self,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
+ ) {
+ self.upgraded().set_installation_manager(manager);
}
-
- pub fn as_rc(&self) -> &std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>> {
- &self.0
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
+ self.upgraded().get_installation_manager()
}
-}
-
-impl From<ComposerHandle> for PartialComposerHandle {
- fn from(c: ComposerHandle) -> Self {
- c.upcast()
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
+ ) {
+ self.upgraded().set_event_dispatcher(event_dispatcher);
}
-}
-
-/// Shared weak reference to \Composer\Composer.
-#[derive(Debug, Clone)]
-pub struct ComposerWeakHandle(std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl ComposerWeakHandle {
- pub fn upgrade(&self) -> Option<ComposerHandle> {
- self.0.upgrade().map(ComposerHandle)
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
+ self.upgraded().get_event_dispatcher()
}
-
- pub fn from_weak(weak: std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(weak)
+ fn is_global(&self) -> bool {
+ self.upgraded().is_global()
+ }
+ fn set_global(&self) {
+ self.upgraded().set_global();
}
}
-/// Borrows a polymorphic `PartialComposer` as a fully-loaded `Composer`.
+/// Downcasts a polymorphic composer handle to a fully-loaded \Composer\Composer.
///
/// Commands obtain their Composer through `require_composer` / `create_composer_instance`,
/// which always yield a fully-loaded instance, so the downcast is infallible here.
-pub fn composer_full(composer: &PartialComposerHandle) -> std::cell::Ref<'_, Composer> {
- std::cell::Ref::map(composer.as_rc().borrow(), |c| {
- c.as_full()
- .expect("a fully loaded Composer is required here")
- })
-}
-
-/// Mutably borrows a polymorphic `PartialComposer` as a fully-loaded `Composer`. See [`composer_full`].
-pub fn composer_full_mut(composer: &PartialComposerHandle) -> std::cell::RefMut<'_, Composer> {
- std::cell::RefMut::map(composer.as_rc().borrow_mut(), |c| {
- c.as_full_mut()
- .expect("a fully loaded Composer is required here")
- })
+pub fn composer_full(composer: &AnyComposerHandle) -> FullComposerHandle {
+ composer
+ .as_full()
+ .expect("a fully loaded Composer is required here")
}