aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/event_dispatcher
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-27 08:44:57 +0900
committernsfisis <nsfisis@gmail.com>2026-06-27 08:44:57 +0900
commit901878ee3f2bee6605b02d321cc4c92bc32fd5b0 (patch)
tree83d8c8c9a24cb95c0656866d328b87c2d4c5127f /crates/shirabe/src/event_dispatcher
parent5c2c72223cb6b4d77a332eeeeff7ee4e82e3f239 (diff)
downloadphp-shirabe-901878ee3f2bee6605b02d321cc4c92bc32fd5b0.tar.gz
php-shirabe-901878ee3f2bee6605b02d321cc4c92bc32fd5b0.tar.zst
php-shirabe-901878ee3f2bee6605b02d321cc4c92bc32fd5b0.zip
refactor(composer): hold managers behind *Interface traits
Composer/PartialComposer exposed its RepositoryManager, InstallationManager, EventDispatcher, Locker, DownloadManager, AutoloadGenerator and ArchiveManager as concrete types, but Composer's public setters (setDownloadManager() etc.) let plugins swap in subclasses. Introduce a *Interface trait per manager and store each as Rc<RefCell<dyn ...Interface>> so a replacement is honored. Only Composer's slots and the sinks fed from its accessors become trait objects; managers injected concretely at construction keep their concrete references, matching PHP semantics. Fluent setters on the affected classes now return () and Locker::update_hash is de-generified to a boxed FnOnce so the traits stay object-safe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/event_dispatcher')
-rw-r--r--crates/shirabe/src/event_dispatcher/event_dispatcher.rs71
1 files changed, 67 insertions, 4 deletions
diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
index f74b4a2..091160e 100644
--- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
+++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
@@ -125,10 +125,8 @@ impl EventDispatcher {
}
/// Set whether script handlers are active or not
- pub fn set_run_scripts(&mut self, run_scripts: bool) -> &mut Self {
+ pub fn set_run_scripts(&mut self, run_scripts: bool) {
self.run_scripts = run_scripts;
-
- self
}
/// Dispatch an event
@@ -1193,7 +1191,7 @@ impl EventDispatcher {
let installation_manager = composer.get_installation_manager();
let package_map = generator.build_package_map(
- &mut installation_manager.borrow_mut(),
+ &mut *installation_manager.borrow_mut(),
package.clone(),
packages,
)?;
@@ -1245,3 +1243,68 @@ impl EventDispatcher {
}
}
}
+
+// Composer's PartialComposer::setEventDispatcher() accepts any EventDispatcher subclass, so plugins
+// may swap in a replacement. The interface captures the methods reached through Composer's accessor
+// and through the `Rc<RefCell<dyn EventDispatcherInterface>>` references fed from it.
+pub trait EventDispatcherInterface: std::fmt::Debug {
+ fn dispatch(
+ &mut self,
+ event_name: Option<&str>,
+ event: Option<&mut dyn EventInterface>,
+ ) -> anyhow::Result<i64>;
+ fn dispatch_script(
+ &mut self,
+ event_name: &str,
+ dev_mode: bool,
+ additional_args: Vec<String>,
+ flags: IndexMap<String, PhpMixed>,
+ ) -> anyhow::Result<i64>;
+ fn dispatch_installer_event(
+ &mut self,
+ event_name: &str,
+ dev_mode: bool,
+ execute_operations: bool,
+ transaction: Transaction,
+ ) -> anyhow::Result<i64>;
+ fn add_listener(&mut self, event_name: &str, listener: Callable, priority: i64);
+ fn has_event_listeners(&mut self, event: &dyn EventInterface) -> bool;
+}
+
+impl EventDispatcherInterface for EventDispatcher {
+ fn dispatch(
+ &mut self,
+ event_name: Option<&str>,
+ event: Option<&mut dyn EventInterface>,
+ ) -> anyhow::Result<i64> {
+ self.dispatch(event_name, event)
+ }
+
+ fn dispatch_script(
+ &mut self,
+ event_name: &str,
+ dev_mode: bool,
+ additional_args: Vec<String>,
+ flags: IndexMap<String, PhpMixed>,
+ ) -> anyhow::Result<i64> {
+ self.dispatch_script(event_name, dev_mode, additional_args, flags)
+ }
+
+ fn dispatch_installer_event(
+ &mut self,
+ event_name: &str,
+ dev_mode: bool,
+ execute_operations: bool,
+ transaction: Transaction,
+ ) -> anyhow::Result<i64> {
+ self.dispatch_installer_event(event_name, dev_mode, execute_operations, transaction)
+ }
+
+ fn add_listener(&mut self, event_name: &str, listener: Callable, priority: i64) {
+ self.add_listener(event_name, listener, priority);
+ }
+
+ fn has_event_listeners(&mut self, event: &dyn EventInterface) -> bool {
+ self.has_event_listeners(event)
+ }
+}