diff options
Diffstat (limited to 'crates/shirabe/src/dependency_resolver/operation')
8 files changed, 126 insertions, 150 deletions
diff --git a/crates/shirabe/src/dependency_resolver/operation/any_operation.rs b/crates/shirabe/src/dependency_resolver/operation/any_operation.rs new file mode 100644 index 00000000..6675b280 --- /dev/null +++ b/crates/shirabe/src/dependency_resolver/operation/any_operation.rs @@ -0,0 +1,92 @@ +//! ref: composer/src/Composer/DependencyResolver/Operation/OperationInterface.php +//! +//! PHP's `OperationInterface` is not ported as a trait. Operations are only ever constructed by the +//! dependency resolver, so a plugin has no way to inject an implementation of its own and the set is +//! closed. The shared implementations PHP puts on `SolverOperation` (`getOperationType()`, +//! `__toString()`) live here. + +use crate::dependency_resolver::operation::{ + InstallOperation, MarkAliasInstalledOperation, MarkAliasUninstalledOperation, SolverOperation, + UninstallOperation, UpdateOperation, +}; +use crate::package::PackageInterfaceHandle; + +/// Any solver operation. +#[derive(Debug, Clone)] +pub enum AnyOperation { + Install(InstallOperation), + Update(UpdateOperation), + Uninstall(UninstallOperation), + MarkAliasInstalled(MarkAliasInstalledOperation), + MarkAliasUninstalled(MarkAliasUninstalledOperation), +} + +impl AnyOperation { + pub fn get_operation_type(&self) -> &'static str { + match self { + Self::Install(_) => InstallOperation::TYPE, + Self::Update(_) => UpdateOperation::TYPE, + Self::Uninstall(_) => UninstallOperation::TYPE, + Self::MarkAliasInstalled(_) => MarkAliasInstalledOperation::TYPE, + Self::MarkAliasUninstalled(_) => MarkAliasUninstalledOperation::TYPE, + } + } + + pub fn show(&self, lock: bool) -> String { + match self { + Self::Install(op) => op.show(lock), + Self::Update(op) => op.show(lock), + Self::Uninstall(op) => op.show(lock), + Self::MarkAliasInstalled(op) => op.show(lock), + Self::MarkAliasUninstalled(op) => op.show(lock), + } + } + + /// The package the operation results in. PHP spells this out at every call site as + /// `$op instanceof UpdateOperation ? $op->getTargetPackage() : $op->getPackage()`. + pub fn get_target_package(&self) -> PackageInterfaceHandle { + match self { + Self::Install(op) => op.get_package(), + Self::Update(op) => op.get_target_package(), + Self::Uninstall(op) => op.get_package(), + Self::MarkAliasInstalled(op) => op.get_package().into(), + Self::MarkAliasUninstalled(op) => op.get_package().into(), + } + } +} + +impl std::fmt::Display for AnyOperation { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.show(false)) + } +} + +impl From<InstallOperation> for AnyOperation { + fn from(op: InstallOperation) -> Self { + Self::Install(op) + } +} + +impl From<UpdateOperation> for AnyOperation { + fn from(op: UpdateOperation) -> Self { + Self::Update(op) + } +} + +impl From<UninstallOperation> for AnyOperation { + fn from(op: UninstallOperation) -> Self { + Self::Uninstall(op) + } +} + +impl From<MarkAliasInstalledOperation> for AnyOperation { + fn from(op: MarkAliasInstalledOperation) -> Self { + Self::MarkAliasInstalled(op) + } +} + +impl From<MarkAliasUninstalledOperation> for AnyOperation { + fn from(op: MarkAliasUninstalledOperation) -> Self { + Self::MarkAliasUninstalled(op) + } +} diff --git a/crates/shirabe/src/dependency_resolver/operation/install_operation.rs b/crates/shirabe/src/dependency_resolver/operation/install_operation.rs index ef492393..05349c2d 100644 --- a/crates/shirabe/src/dependency_resolver/operation/install_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/install_operation.rs @@ -1,10 +1,9 @@ //! ref: composer/src/Composer/DependencyResolver/Operation/InstallOperation.php -use crate::dependency_resolver::operation::OperationInterface; use crate::dependency_resolver::operation::SolverOperation; use crate::package::PackageInterfaceHandle; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct InstallOperation { pub(crate) package: PackageInterfaceHandle, } @@ -18,6 +17,10 @@ impl InstallOperation { self.package.clone() } + pub fn show(&self, lock: bool) -> String { + Self::format(self.package.clone(), lock) + } + pub fn format(package: PackageInterfaceHandle, lock: bool) -> String { format!( "{}<info>{}</info> (<comment>{}</comment>)", @@ -32,28 +35,6 @@ impl SolverOperation for InstallOperation { const TYPE: &'static str = "install"; } -impl OperationInterface for InstallOperation { - fn as_any(&self) -> &dyn std::any::Any { - self - } - - fn get_operation_type(&self) -> String { - Self::TYPE.to_string() - } - - fn show(&self, lock: bool) -> String { - Self::format(self.package.clone(), lock) - } - - fn as_install_operation(&self) -> Option<&InstallOperation> { - Some(self) - } - - fn get_package(&self) -> PackageInterfaceHandle { - self.package.clone() - } -} - impl std::fmt::Display for InstallOperation { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.show(false)) diff --git a/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs b/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs index 28bf511a..72066204 100644 --- a/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs @@ -1,10 +1,9 @@ //! ref: composer/src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php -use crate::dependency_resolver::operation::OperationInterface; use crate::dependency_resolver::operation::SolverOperation; use crate::package::AliasPackageHandle; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct MarkAliasInstalledOperation { pub(crate) package: AliasPackageHandle, } @@ -17,22 +16,8 @@ impl MarkAliasInstalledOperation { pub fn get_package(&self) -> AliasPackageHandle { self.package.clone() } -} - -impl SolverOperation for MarkAliasInstalledOperation { - const TYPE: &'static str = "markAliasInstalled"; -} - -impl OperationInterface for MarkAliasInstalledOperation { - fn as_any(&self) -> &dyn std::any::Any { - self - } - fn get_operation_type(&self) -> String { - Self::TYPE.to_string() - } - - fn show(&self, _lock: bool) -> String { + pub fn show(&self, _lock: bool) -> String { format!( "Marking <info>{}</info> (<comment>{}</comment>) as installed, alias of <info>{}</info> (<comment>{}</comment>)", self.package.get_pretty_name(), @@ -44,10 +29,10 @@ impl OperationInterface for MarkAliasInstalledOperation { .get_full_pretty_version(true, crate::package::DisplayMode::SourceRefIfDev), ) } +} - fn get_package(&self) -> crate::package::PackageInterfaceHandle { - self.package.clone().into() - } +impl SolverOperation for MarkAliasInstalledOperation { + const TYPE: &'static str = "markAliasInstalled"; } impl std::fmt::Display for MarkAliasInstalledOperation { diff --git a/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs b/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs index 3c0de332..4e4000df 100644 --- a/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs @@ -1,10 +1,9 @@ //! ref: composer/src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.php -use crate::dependency_resolver::operation::OperationInterface; use crate::dependency_resolver::operation::SolverOperation; use crate::package::AliasPackageHandle; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct MarkAliasUninstalledOperation { pub(crate) package: AliasPackageHandle, } @@ -17,22 +16,8 @@ impl MarkAliasUninstalledOperation { pub fn get_package(&self) -> AliasPackageHandle { self.package.clone() } -} - -impl SolverOperation for MarkAliasUninstalledOperation { - const TYPE: &'static str = "markAliasUninstalled"; -} - -impl OperationInterface for MarkAliasUninstalledOperation { - fn as_any(&self) -> &dyn std::any::Any { - self - } - fn get_operation_type(&self) -> String { - Self::TYPE.to_string() - } - - fn show(&self, _lock: bool) -> String { + pub fn show(&self, _lock: bool) -> String { format!( "Marking <info>{}</info> (<comment>{}</comment>) as uninstalled, alias of <info>{}</info> (<comment>{}</comment>)", self.package.get_pretty_name(), @@ -44,10 +29,10 @@ impl OperationInterface for MarkAliasUninstalledOperation { .get_full_pretty_version(true, crate::package::DisplayMode::SourceRefIfDev), ) } +} - fn get_package(&self) -> crate::package::PackageInterfaceHandle { - self.package.clone().into() - } +impl SolverOperation for MarkAliasUninstalledOperation { + const TYPE: &'static str = "markAliasUninstalled"; } impl std::fmt::Display for MarkAliasUninstalledOperation { diff --git a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs b/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs deleted file mode 100644 index 30ed8eb5..00000000 --- a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! ref: composer/src/Composer/DependencyResolver/Operation/OperationInterface.php - -use crate::dependency_resolver::operation::InstallOperation; -use crate::dependency_resolver::operation::UninstallOperation; -use crate::dependency_resolver::operation::UpdateOperation; - -pub trait OperationInterface: std::fmt::Display + std::fmt::Debug { - fn as_any(&self) -> &dyn std::any::Any; - - fn get_operation_type(&self) -> String; - - fn show(&self, lock: bool) -> String; - - fn as_install_operation(&self) -> Option<&InstallOperation> { - None - } - - fn as_update_operation(&self) -> Option<&UpdateOperation> { - None - } - - fn as_uninstall_operation(&self) -> Option<&UninstallOperation> { - None - } - - /// PHP duck-typed accessor. Only InstallOperation/UninstallOperation/MarkAlias*Operation - /// expose this; UpdateOperation has getInitialPackage()/getTargetPackage() instead. - fn get_package(&self) -> crate::package::PackageInterfaceHandle { - todo!("get_package is not available on this operation type") - } -} diff --git a/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs b/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs index 2710ec50..eb9c6315 100644 --- a/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs @@ -1,11 +1,9 @@ //! ref: composer/src/Composer/DependencyResolver/Operation/SolverOperation.php -use crate::dependency_resolver::operation::OperationInterface; - -pub trait SolverOperation: OperationInterface { +/// PHP's abstract `SolverOperation` carries the per-class `TYPE` constant and the +/// `getOperationType()` / `__toString()` implementations shared by every operation. Only the +/// constant remains here; the shared implementations live on +/// [`AnyOperation`](crate::dependency_resolver::operation::AnyOperation). +pub trait SolverOperation { const TYPE: &'static str; - - fn get_operation_type(&self) -> &str { - Self::TYPE - } } diff --git a/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs b/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs index d2dd6651..2fd35af5 100644 --- a/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs @@ -1,10 +1,9 @@ //! ref: composer/src/Composer/DependencyResolver/Operation/UninstallOperation.php -use crate::dependency_resolver::operation::OperationInterface; use crate::dependency_resolver::operation::SolverOperation; use crate::package::PackageInterfaceHandle; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct UninstallOperation { pub(crate) package: PackageInterfaceHandle, } @@ -18,6 +17,10 @@ impl UninstallOperation { self.package.clone() } + pub fn show(&self, lock: bool) -> String { + Self::format(self.package.clone(), lock) + } + pub fn format(package: PackageInterfaceHandle, _lock: bool) -> String { format!( "Removing <info>{}</info> (<comment>{}</comment>)", @@ -31,28 +34,6 @@ impl SolverOperation for UninstallOperation { const TYPE: &'static str = "uninstall"; } -impl OperationInterface for UninstallOperation { - fn as_any(&self) -> &dyn std::any::Any { - self - } - - fn get_operation_type(&self) -> String { - Self::TYPE.to_string() - } - - fn show(&self, lock: bool) -> String { - Self::format(self.package.clone(), lock) - } - - fn as_uninstall_operation(&self) -> Option<&UninstallOperation> { - Some(self) - } - - fn get_package(&self) -> PackageInterfaceHandle { - self.package.clone() - } -} - impl std::fmt::Display for UninstallOperation { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.show(false)) diff --git a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs index 76b17189..a06a9cdc 100644 --- a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs @@ -1,11 +1,10 @@ //! ref: composer/src/Composer/DependencyResolver/Operation/UpdateOperation.php -use crate::dependency_resolver::operation::OperationInterface; use crate::dependency_resolver::operation::SolverOperation; use crate::package::PackageInterfaceHandle; use crate::package::version::VersionParser; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct UpdateOperation { pub(crate) initial_package: PackageInterfaceHandle, pub(crate) target_package: PackageInterfaceHandle, @@ -27,6 +26,14 @@ impl UpdateOperation { self.target_package.clone() } + pub fn show(&self, lock: bool) -> String { + Self::format( + self.initial_package.clone(), + self.target_package.clone(), + lock, + ) + } + pub fn format( initial_package: PackageInterfaceHandle, target_package: PackageInterfaceHandle, @@ -78,28 +85,6 @@ impl SolverOperation for UpdateOperation { const TYPE: &'static str = "update"; } -impl OperationInterface for UpdateOperation { - fn as_any(&self) -> &dyn std::any::Any { - self - } - - fn get_operation_type(&self) -> String { - Self::TYPE.to_string() - } - - fn show(&self, lock: bool) -> String { - Self::format( - self.initial_package.clone(), - self.target_package.clone(), - lock, - ) - } - - fn as_update_operation(&self) -> Option<&UpdateOperation> { - Some(self) - } -} - impl std::fmt::Display for UpdateOperation { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.show(false)) |
