aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-03 23:06:16 +0900
committernsfisis <nsfisis@gmail.com>2026-06-03 23:06:16 +0900
commit60bfd667e4a98f5463a5bd5f2d0259bd0eeb0a5e (patch)
treefd701c69882f6ce67da31fdc3ce0693e3141fddc /crates
parenteba99f7e5f38d9501b37d9b188b6f324a947dc74 (diff)
downloadphp-shirabe-60bfd667e4a98f5463a5bd5f2d0259bd0eeb0a5e.tar.gz
php-shirabe-60bfd667e4a98f5463a5bd5f2d0259bd0eeb0a5e.tar.zst
php-shirabe-60bfd667e4a98f5463a5bd5f2d0259bd0eeb0a5e.zip
feat(downloader): wire as_* downcasts for file/archive/path/git downloaders
Override DownloaderInterface's as_change_report_interface / as_vcs_capable_downloader_interface / as_dvcs_downloader_interface so PHP-style instanceof checks resolve to the concrete sub-interface: FileDownloader and the six archive downloaders (Zip/Tar/Gzip/Xz/Rar/Phar) plus PathDownloader gain ChangeReportInterface (archives/path delegate to the inner FileDownloader), PathDownloader exposes VcsCapableDownloaderInterface, and GitDownloader exposes DvcsDownloaderInterface. The default None impls remain correct for downloaders that do not implement a given sub-interface, so their stale TODO markers are dropped. VCS downloaders' ChangeReport/VcsCapable conformance follows separately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe/src/downloader/downloader_interface.rs3
-rw-r--r--crates/shirabe/src/downloader/file_downloader.rs4
-rw-r--r--crates/shirabe/src/downloader/git_downloader.rs6
-rw-r--r--crates/shirabe/src/downloader/gzip_downloader.rs15
-rw-r--r--crates/shirabe/src/downloader/path_downloader.rs21
-rw-r--r--crates/shirabe/src/downloader/phar_downloader.rs15
-rw-r--r--crates/shirabe/src/downloader/rar_downloader.rs15
-rw-r--r--crates/shirabe/src/downloader/tar_downloader.rs15
-rw-r--r--crates/shirabe/src/downloader/xz_downloader.rs15
-rw-r--r--crates/shirabe/src/downloader/zip_downloader.rs15
10 files changed, 121 insertions, 3 deletions
diff --git a/crates/shirabe/src/downloader/downloader_interface.rs b/crates/shirabe/src/downloader/downloader_interface.rs
index 986db28..873438e 100644
--- a/crates/shirabe/src/downloader/downloader_interface.rs
+++ b/crates/shirabe/src/downloader/downloader_interface.rs
@@ -80,19 +80,16 @@ pub trait DownloaderInterface: std::fmt::Debug {
prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>>;
- /// TODO(phase-b): runtime downcast helpers for PHP `instanceof` checks.
fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
None
}
- /// TODO(phase-b): runtime downcast helpers for PHP `instanceof` checks.
fn as_vcs_capable_downloader_interface(
&self,
) -> Option<&dyn crate::downloader::VcsCapableDownloaderInterface> {
None
}
- /// TODO(phase-b): runtime downcast helpers for PHP `instanceof` checks.
fn as_dvcs_downloader_interface(
&self,
) -> Option<&dyn crate::downloader::DvcsDownloaderInterface> {
diff --git a/crates/shirabe/src/downloader/file_downloader.rs b/crates/shirabe/src/downloader/file_downloader.rs
index dadf8fb..5b66a9f 100644
--- a/crates/shirabe/src/downloader/file_downloader.rs
+++ b/crates/shirabe/src/downloader/file_downloader.rs
@@ -153,6 +153,10 @@ impl DownloaderInterface for FileDownloader {
"dist".to_owned()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
/// @inheritDoc
async fn download(
&self,
diff --git a/crates/shirabe/src/downloader/git_downloader.rs b/crates/shirabe/src/downloader/git_downloader.rs
index ed6f913..6d545ce 100644
--- a/crates/shirabe/src/downloader/git_downloader.rs
+++ b/crates/shirabe/src/downloader/git_downloader.rs
@@ -1380,6 +1380,12 @@ impl crate::downloader::DownloaderInterface for GitDownloader {
todo!()
}
+ fn as_dvcs_downloader_interface(
+ &self,
+ ) -> Option<&dyn crate::downloader::DvcsDownloaderInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
_package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs
index 00adca9..337e298 100644
--- a/crates/shirabe/src/downloader/gzip_downloader.rs
+++ b/crates/shirabe/src/downloader/gzip_downloader.rs
@@ -3,6 +3,7 @@
use crate::cache::Cache;
use crate::config::Config;
use crate::downloader::ArchiveDownloader;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::FileDownloader;
use crate::event_dispatcher::EventDispatcher;
use crate::io::IOInterface;
@@ -129,12 +130,26 @@ impl GzipDownloader {
}
}
+impl ChangeReportInterface for GzipDownloader {
+ fn get_local_changes(
+ &self,
+ package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ self.inner.get_local_changes(package, path)
+ }
+}
+
#[async_trait::async_trait(?Send)]
impl crate::downloader::DownloaderInterface for GzipDownloader {
fn get_installation_source(&self) -> String {
self.inner.get_installation_source()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/path_downloader.rs b/crates/shirabe/src/downloader/path_downloader.rs
index c50856e..3eb2a48 100644
--- a/crates/shirabe/src/downloader/path_downloader.rs
+++ b/crates/shirabe/src/downloader/path_downloader.rs
@@ -14,6 +14,7 @@ use crate::cache::Cache;
use crate::config::Config;
use crate::dependency_resolver::operation::InstallOperation;
use crate::dependency_resolver::operation::UninstallOperation;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
use crate::downloader::FileDownloader;
use crate::downloader::VcsCapableDownloaderInterface;
@@ -534,6 +535,16 @@ impl VcsCapableDownloaderInterface for PathDownloader {
}
}
+impl crate::downloader::ChangeReportInterface for PathDownloader {
+ fn get_local_changes(
+ &self,
+ package: PackageInterfaceHandle,
+ path: &str,
+ ) -> anyhow::Result<Option<String>> {
+ self.inner.get_local_changes(package, path)
+ }
+}
+
// TODO(phase-b): wire up PathDownloader trait properly. PathDownloader extends FileDownloader and
// overrides download/install/remove with &mut self signatures that diverge from the trait. The
// trait methods here delegate to the inner FileDownloader; the bespoke overrides on the struct
@@ -544,6 +555,16 @@ impl DownloaderInterface for PathDownloader {
self.inner.get_installation_source()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
+ fn as_vcs_capable_downloader_interface(
+ &self,
+ ) -> Option<&dyn crate::downloader::VcsCapableDownloaderInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/phar_downloader.rs b/crates/shirabe/src/downloader/phar_downloader.rs
index 6a4ac97..46fdd84 100644
--- a/crates/shirabe/src/downloader/phar_downloader.rs
+++ b/crates/shirabe/src/downloader/phar_downloader.rs
@@ -3,6 +3,7 @@
use crate::cache::Cache;
use crate::config::Config;
use crate::downloader::ArchiveDownloader;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
use crate::downloader::FileDownloader;
use crate::event_dispatcher::EventDispatcher;
@@ -63,12 +64,26 @@ impl PharDownloader {
}
}
+impl ChangeReportInterface for PharDownloader {
+ fn get_local_changes(
+ &self,
+ package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ self.inner.get_local_changes(package, path)
+ }
+}
+
#[async_trait::async_trait(?Send)]
impl DownloaderInterface for PharDownloader {
fn get_installation_source(&self) -> String {
self.inner.get_installation_source()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/rar_downloader.rs b/crates/shirabe/src/downloader/rar_downloader.rs
index 9ce6c51..4385bc3 100644
--- a/crates/shirabe/src/downloader/rar_downloader.rs
+++ b/crates/shirabe/src/downloader/rar_downloader.rs
@@ -3,6 +3,7 @@
use crate::cache::Cache;
use crate::config::Config;
use crate::downloader::ArchiveDownloader;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::FileDownloader;
use crate::event_dispatcher::EventDispatcher;
use crate::io::IOInterface;
@@ -143,12 +144,26 @@ impl RarDownloader {
}
}
+impl ChangeReportInterface for RarDownloader {
+ fn get_local_changes(
+ &self,
+ package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ self.inner.get_local_changes(package, path)
+ }
+}
+
#[async_trait::async_trait(?Send)]
impl crate::downloader::DownloaderInterface for RarDownloader {
fn get_installation_source(&self) -> String {
self.inner.get_installation_source()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/tar_downloader.rs b/crates/shirabe/src/downloader/tar_downloader.rs
index 07d8a5f..6cf1176 100644
--- a/crates/shirabe/src/downloader/tar_downloader.rs
+++ b/crates/shirabe/src/downloader/tar_downloader.rs
@@ -3,6 +3,7 @@
use crate::cache::Cache;
use crate::config::Config;
use crate::downloader::ArchiveDownloader;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
use crate::downloader::FileDownloader;
use crate::event_dispatcher::EventDispatcher;
@@ -58,12 +59,26 @@ impl TarDownloader {
}
}
+impl ChangeReportInterface for TarDownloader {
+ fn get_local_changes(
+ &self,
+ package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ self.inner.get_local_changes(package, path)
+ }
+}
+
#[async_trait::async_trait(?Send)]
impl DownloaderInterface for TarDownloader {
fn get_installation_source(&self) -> String {
self.inner.get_installation_source()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/xz_downloader.rs b/crates/shirabe/src/downloader/xz_downloader.rs
index ac8b6ba..976497a 100644
--- a/crates/shirabe/src/downloader/xz_downloader.rs
+++ b/crates/shirabe/src/downloader/xz_downloader.rs
@@ -3,6 +3,7 @@
use crate::cache::Cache;
use crate::config::Config;
use crate::downloader::ArchiveDownloader;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::FileDownloader;
use crate::event_dispatcher::EventDispatcher;
use crate::io::IOInterface;
@@ -77,12 +78,26 @@ impl XzDownloader {
}
}
+impl ChangeReportInterface for XzDownloader {
+ fn get_local_changes(
+ &self,
+ package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ self.inner.get_local_changes(package, path)
+ }
+}
+
#[async_trait::async_trait(?Send)]
impl crate::downloader::DownloaderInterface for XzDownloader {
fn get_installation_source(&self) -> String {
self.inner.get_installation_source()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/zip_downloader.rs b/crates/shirabe/src/downloader/zip_downloader.rs
index 17eeae5..3fda248 100644
--- a/crates/shirabe/src/downloader/zip_downloader.rs
+++ b/crates/shirabe/src/downloader/zip_downloader.rs
@@ -1,6 +1,7 @@
//! ref: composer/src/Composer/Downloader/ZipDownloader.php
use crate::downloader::ArchiveDownloader;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
use crate::downloader::FileDownloader;
use crate::io::IOInterface;
@@ -553,6 +554,16 @@ impl ZipDownloader {
}
}
+impl ChangeReportInterface for ZipDownloader {
+ fn get_local_changes(
+ &self,
+ package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ self.inner.get_local_changes(package, path)
+ }
+}
+
// TODO(phase-b): ZipDownloader::download is overridden with extra setup (UNZIP_COMMANDS init,
// etc.). The trait method here delegates straight to the inner FileDownloader; the bespoke
// override on the struct itself takes &mut self and is not yet routed through the trait.
@@ -562,6 +573,10 @@ impl crate::downloader::DownloaderInterface for ZipDownloader {
self.inner.get_installation_source()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
package: PackageInterfaceHandle,