From dbdecaf5a1c54a876b7ee0153d58dd39b1080f97 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 23 May 2026 23:14:52 +0900 Subject: refactor(semver): change ConstraintInterface to a closed enum Replace the dyn ConstraintInterface trait objects with an AnyConstraint enum closing over its four implementors (Simple, Multi, MatchAll, MatchNone), mirroring the earlier Rule enum conversion. Rename constraint.rs to simple_constraint.rs to match the renamed Constraint type. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../src/repository/advisory_provider_interface.rs | 4 +- crates/shirabe/src/repository/array_repository.rs | 43 ++++++---- .../shirabe/src/repository/composer_repository.rs | 91 ++++++++++------------ .../shirabe/src/repository/composite_repository.rs | 13 ++-- crates/shirabe/src/repository/filter_repository.rs | 6 +- .../src/repository/installed_array_repository.rs | 4 +- .../repository/installed_filesystem_repository.rs | 4 +- .../shirabe/src/repository/installed_repository.rs | 80 +++++++++++-------- .../src/repository/lock_array_repository.rs | 4 +- .../shirabe/src/repository/package_repository.rs | 4 +- .../shirabe/src/repository/platform_repository.rs | 14 ++-- .../shirabe/src/repository/repository_interface.rs | 8 +- .../shirabe/src/repository/repository_manager.rs | 10 +-- crates/shirabe/src/repository/repository_set.rs | 52 +++++++------ .../src/repository/root_package_repository.rs | 5 +- crates/shirabe/src/repository/vcs_repository.rs | 22 ++++-- 16 files changed, 198 insertions(+), 166 deletions(-) (limited to 'crates/shirabe/src/repository') diff --git a/crates/shirabe/src/repository/advisory_provider_interface.rs b/crates/shirabe/src/repository/advisory_provider_interface.rs index 4c08a63d..0de9c429 100644 --- a/crates/shirabe/src/repository/advisory_provider_interface.rs +++ b/crates/shirabe/src/repository/advisory_provider_interface.rs @@ -3,7 +3,7 @@ use crate::advisory::PartialSecurityAdvisory; use crate::advisory::SecurityAdvisory; use indexmap::IndexMap; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub enum PartialOrSecurityAdvisory { @@ -31,7 +31,7 @@ pub trait AdvisoryProviderInterface { fn get_security_advisories( &self, - package_constraint_map: IndexMap>, + package_constraint_map: IndexMap, allow_partial_advisories: bool, ) -> anyhow::Result; } diff --git a/crates/shirabe/src/repository/array_repository.rs b/crates/shirabe/src/repository/array_repository.rs index f8d2e0c2..fe45849a 100644 --- a/crates/shirabe/src/repository/array_repository.rs +++ b/crates/shirabe/src/repository/array_repository.rs @@ -10,8 +10,8 @@ use shirabe_php_shim::{ Countable, InvalidArgumentException, LogicException, implode, preg_quote, spl_object_hash, strtolower, }; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::package::AliasPackage; use crate::package::BasePackage; @@ -162,7 +162,7 @@ impl RepositoryInterface for ArrayRepository { fn load_packages( &self, - package_name_map: IndexMap>>, + package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, @@ -178,7 +178,14 @@ impl RepositoryInterface for ArrayRepository { .unwrap(); let constraint_matches = match constraint_opt { None => true, - Some(c) => c.matches(&Constraint::new("==", package.get_version())), + Some(c) => c.matches( + &SimpleConstraint::new( + "==".to_string(), + package.get_version().to_string(), + None, + ) + .into(), + ), }; if constraint_matches && StabilityFilter::is_package_acceptable( @@ -233,18 +240,22 @@ impl RepositoryInterface for ArrayRepository { ) -> Option> { let name = strtolower(name); - let constraint: Box = match constraint { + let constraint: AnyConstraint = match constraint { FindPackageConstraint::Constraint(c) => c, FindPackageConstraint::String(s) => { let version_parser = VersionParser::new(); - version_parser.parse_constraints(&s).unwrap().clone_box() + version_parser.parse_constraints(&s).unwrap().clone() } }; for package in self.get_packages() { if name == PackageInterface::get_name(package.as_ref()) { - let pkg_constraint = Constraint::new("==", package.get_version()); - if constraint.matches(&pkg_constraint) { + let pkg_constraint = SimpleConstraint::new( + "==".to_string(), + package.get_version().to_string(), + None, + ); + if constraint.matches(&pkg_constraint.into()) { return Some(package); } } @@ -262,22 +273,26 @@ impl RepositoryInterface for ArrayRepository { let name = strtolower(name); let mut packages = vec![]; - let constraint: Option> = match constraint { + let constraint: Option = match constraint { None => None, Some(FindPackageConstraint::Constraint(c)) => Some(c), Some(FindPackageConstraint::String(s)) => { let version_parser = VersionParser::new(); - Some(version_parser.parse_constraints(&s).unwrap().clone_box()) + Some(version_parser.parse_constraints(&s).unwrap().clone()) } }; for package in self.get_packages() { if name == PackageInterface::get_name(package.as_ref()) { if constraint.is_none() - || constraint - .as_ref() - .unwrap() - .matches(&Constraint::new("==", package.get_version())) + || constraint.as_ref().unwrap().matches( + &SimpleConstraint::new( + "==".to_string(), + package.get_version().to_string(), + None, + ) + .into(), + ) { packages.push(package); } diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 4bd54422..9752bc09 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -11,9 +11,9 @@ use shirabe_php_shim::{ }; use shirabe_semver::compiling_matcher::CompilingMatcher; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::MatchAllConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::advisory::PartialSecurityAdvisory; use crate::cache::Cache; @@ -327,11 +327,11 @@ impl ComposerRepository { let has_providers = self.has_providers()?; let name = strtolower(&name); - let constraint: Box = match constraint { - PhpMixed::String(s) => self.version_parser.parse_constraints(&s)?.clone_box(), + let constraint: AnyConstraint = match constraint { + PhpMixed::String(s) => self.version_parser.parse_constraints(&s)?.clone(), _ => { // already a ConstraintInterface object passed as opaque PhpMixed - self.version_parser.parse_constraints("")?.clone_box() + self.version_parser.parse_constraints("")?.clone() } }; @@ -345,7 +345,7 @@ impl ComposerRepository { let packages = self.what_provides(&name, None, None, IndexMap::new())?; let packages_vec: Vec> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, Some(&*constraint), true) { + match self.filter_packages(packages_vec, Some(&constraint), true) { FindPackageReturn::Package(p) => Some(p), _ => None, }, @@ -356,7 +356,7 @@ impl ComposerRepository { return Ok(None); } - let mut map: IndexMap>> = IndexMap::new(); + let mut map: IndexMap> = IndexMap::new(); map.insert(name.clone(), Some(constraint)); let packages = self.load_async_packages(map, None, None, IndexMap::new())?; @@ -374,7 +374,7 @@ impl ComposerRepository { self.what_provides(&provider_name, None, None, IndexMap::new())?; let packages_vec: Vec> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, Some(&*constraint), true) { + match self.filter_packages(packages_vec, Some(&constraint), true) { FindPackageReturn::Package(p) => Some(p), _ => None, }, @@ -401,11 +401,9 @@ impl ComposerRepository { let has_providers = self.has_providers()?; let name = strtolower(&name); - let constraint: Option> = match constraint { + let constraint: Option = match constraint { None => None, - Some(PhpMixed::String(s)) => { - Some(self.version_parser.parse_constraints(&s)?.clone_box()) - } + Some(PhpMixed::String(s)) => Some(self.version_parser.parse_constraints(&s)?.clone()), Some(_) => None, }; @@ -419,7 +417,7 @@ impl ComposerRepository { let packages = self.what_provides(&name, None, None, IndexMap::new())?; let packages_vec: Vec> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, constraint.as_deref(), false) { + match self.filter_packages(packages_vec, constraint.as_ref(), false) { FindPackageReturn::Packages(v) => v, _ => vec![], }, @@ -430,7 +428,7 @@ impl ComposerRepository { return Ok(vec![]); } - let mut map: IndexMap>> = IndexMap::new(); + let mut map: IndexMap> = IndexMap::new(); map.insert(name.clone(), constraint); let result = self.load_async_packages(map, None, None, IndexMap::new())?; @@ -444,7 +442,7 @@ impl ComposerRepository { self.what_provides(&provider_name, None, None, IndexMap::new())?; let packages_vec: Vec> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, constraint.as_deref(), false) { + match self.filter_packages(packages_vec, constraint.as_ref(), false) { FindPackageReturn::Packages(v) => v, _ => vec![], }, @@ -464,7 +462,7 @@ impl ComposerRepository { fn filter_packages( &self, packages: Vec>, - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, return_first_match: bool, ) -> FindPackageReturn { if constraint.is_none() { @@ -482,9 +480,10 @@ impl ComposerRepository { let mut filtered_packages: Vec> = Vec::new(); for package in packages.into_iter() { - let pkg_constraint = Constraint::new("==", package.get_version().to_string()); + let pkg_constraint = + SimpleConstraint::new("==".to_string(), package.get_version().to_string(), None); - if constraint.matches(&pkg_constraint) { + if constraint.matches(&pkg_constraint.into()) { if return_first_match { return FindPackageReturn::Package(package); } @@ -506,15 +505,10 @@ impl ComposerRepository { if self.lazy_providers_url.is_some() { if let Some(ref available_packages) = self.available_packages.clone() { if self.available_package_patterns.is_none() { - let mut package_map: IndexMap>> = - IndexMap::new(); + let mut package_map: IndexMap> = IndexMap::new(); for name in available_packages.values() { - package_map.insert( - name.clone(), - Some( - Box::new(MatchAllConstraint::new()) as Box - ), - ); + package_map + .insert(name.clone(), Some(MatchAllConstraint::new(None).into())); } let result = @@ -715,7 +709,7 @@ impl ComposerRepository { pub fn load_packages( &mut self, - mut package_name_map: IndexMap>>, + mut package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, @@ -767,7 +761,7 @@ impl ComposerRepository { )?; let constraint = package_name_map .get(&name) - .and_then(|c| c.as_ref().map(|c| c.clone_box())); + .and_then(|c| c.as_ref().map(|c| c.clone())); for (_uid, candidate) in candidates.iter() { if candidate.get_name() != name { return Err(LogicException { @@ -780,8 +774,12 @@ impl ComposerRepository { let matches_constraint = match &constraint { None => true, Some(c) => { - let pkg_c = Constraint::new("==", candidate.get_version().to_string()); - c.matches(&pkg_c) + let pkg_c = SimpleConstraint::new( + "==".to_string(), + candidate.get_version().to_string(), + None, + ); + c.matches(&pkg_c.into()) } }; if matches_constraint { @@ -1025,7 +1023,7 @@ impl ComposerRepository { /// @inheritDoc pub fn get_security_advisories( &mut self, - mut package_constraint_map: IndexMap>, + mut package_constraint_map: IndexMap, allow_partial_advisories: bool, ) -> anyhow::Result { self.load_root_server_file(Some(600))?; @@ -1059,7 +1057,7 @@ impl ComposerRepository { let repo_name = self.get_repo_name(); let create = |data: &IndexMap, name: &str, - package_constraint_map: &IndexMap>| + package_constraint_map: &IndexMap| -> anyhow::Result> { let advisory = PartialSecurityAdvisory::create(name, data, &semver_parser)?; let is_full = matches!(advisory, PartialOrSecurityAdvisory::Full(_)); @@ -1081,11 +1079,11 @@ impl ComposerRepository { } .into()); } - let affected_versions: &dyn ConstraintInterface = match &advisory { - PartialOrSecurityAdvisory::Partial(p) => &*p.affected_versions, + let affected_versions: &AnyConstraint = match &advisory { + PartialOrSecurityAdvisory::Partial(p) => &p.affected_versions, PartialOrSecurityAdvisory::Full(p) => p.affected_versions(), }; - let constraint = package_constraint_map.get(name).map(|c| &**c); + let constraint = package_constraint_map.get(name); if let Some(c) = constraint { if !affected_versions.matches(c) { return Ok(None); @@ -1795,7 +1793,7 @@ impl ComposerRepository { /// @param packageNames array of package name => ConstraintInterface|null - if a constraint is provided, only packages matching it will be loaded fn load_async_packages( &mut self, - mut package_names: IndexMap>>, + mut package_names: IndexMap>, acceptable_stabilities: Option<&IndexMap>, stability_flags: Option<&IndexMap>, already_loaded: IndexMap>>, @@ -1820,7 +1818,7 @@ impl ComposerRepository { for name in names_snapshot { let constraint = package_names .get(&name) - .and_then(|c| c.as_ref().map(|c| c.clone_box())); + .and_then(|c| c.as_ref().map(|c| c.clone())); if acceptable_stabilities.is_none() || stability_flags.is_none() || StabilityFilter::is_package_acceptable( @@ -1840,11 +1838,10 @@ impl ComposerRepository { } } - let names_iter: Vec<(String, Option>)> = package_names + let names_iter: Vec<(String, Option)> = package_names .iter() .map(|(k, v)| { - let cloned: Option> = - v.as_ref().map(|c| dyn_clone_constraint(&**c)); + let cloned: Option = v.clone(); (k.clone(), cloned) }) .collect(); @@ -1972,7 +1969,7 @@ impl ComposerRepository { } let acceptable = ComposerRepository::is_version_acceptable_static( - constraint.as_deref(), + constraint.as_ref(), &real_name, &version, acceptable_stabilities, @@ -2093,7 +2090,7 @@ impl ComposerRepository { /// @param name package name (must be lowercased already) fn is_version_acceptable( &self, - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, name: &str, version_data: &IndexMap, acceptable_stabilities: Option<&IndexMap>, @@ -2110,7 +2107,7 @@ impl ComposerRepository { } fn is_version_acceptable_static( - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, name: &str, version_data: &IndexMap, acceptable_stabilities: Option<&IndexMap>, @@ -2128,7 +2125,7 @@ impl ComposerRepository { fn is_version_acceptable_with_loader( loader: &ArrayLoader, - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, name: &str, version_data: &IndexMap, acceptable_stabilities: Option<&IndexMap>, @@ -2160,7 +2157,7 @@ impl ComposerRepository { } if let Some(c) = constraint { - if !CompilingMatcher::r#match(c, Constraint::OP_EQ, version.clone()) { + if !CompilingMatcher::r#match(c, SimpleConstraint::OP_EQ, version.clone()) { continue; } } @@ -3492,7 +3489,3 @@ fn clone_root_data(rd: &RootData) -> RootData { fn dyn_clone_box(_pkg: &dyn BasePackage) -> Box { todo!() } - -fn dyn_clone_constraint(_c: &dyn ConstraintInterface) -> Box { - todo!() -} diff --git a/crates/shirabe/src/repository/composite_repository.rs b/crates/shirabe/src/repository/composite_repository.rs index b3ac1dd9..66718954 100644 --- a/crates/shirabe/src/repository/composite_repository.rs +++ b/crates/shirabe/src/repository/composite_repository.rs @@ -3,7 +3,7 @@ use std::any::Any; use indexmap::IndexMap; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::package::BasePackage; use crate::package::PackageInterface; @@ -111,7 +111,7 @@ impl RepositoryInterface for CompositeRepository { fn load_packages( &self, - package_name_map: IndexMap>>, + package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, @@ -121,11 +121,10 @@ impl RepositoryInterface for CompositeRepository { for repository in &self.repositories { // TODO(phase-b): manual deep clone since trait objects in maps don't derive Clone. - let name_map_cloned: IndexMap>> = - package_name_map - .iter() - .map(|(k, v)| (k.clone(), v.as_ref().map(|c| c.clone_box()))) - .collect(); + let name_map_cloned: IndexMap> = package_name_map + .iter() + .map(|(k, v)| (k.clone(), v.as_ref().map(|c| c.clone()))) + .collect(); let already_loaded_cloned: IndexMap< String, IndexMap>, diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs index 8a0e6f62..a3cb18be 100644 --- a/crates/shirabe/src/repository/filter_repository.rs +++ b/crates/shirabe/src/repository/filter_repository.rs @@ -10,7 +10,7 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use shirabe_php_shim::{InvalidArgumentException, PhpMixed}; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub struct FilterRepository { @@ -187,7 +187,7 @@ impl RepositoryInterface for FilterRepository { fn load_packages( &self, - mut package_name_map: IndexMap>>, + mut package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, @@ -272,7 +272,7 @@ impl AdvisoryProviderInterface for FilterRepository { fn get_security_advisories( &self, - mut package_constraint_map: IndexMap>, + mut package_constraint_map: IndexMap, allow_partial_advisories: bool, ) -> anyhow::Result { if let Some(advisory_repo) = self.repo.as_advisory_provider() { diff --git a/crates/shirabe/src/repository/installed_array_repository.rs b/crates/shirabe/src/repository/installed_array_repository.rs index fd273b95..b089df6e 100644 --- a/crates/shirabe/src/repository/installed_array_repository.rs +++ b/crates/shirabe/src/repository/installed_array_repository.rs @@ -2,7 +2,7 @@ use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::package::BasePackage; use crate::package::PackageInterface; @@ -114,7 +114,7 @@ impl RepositoryInterface for InstalledArrayRepository { } fn load_packages( &self, - _package_name_map: IndexMap>>, + _package_name_map: IndexMap>, _acceptable_stabilities: IndexMap, _stability_flags: IndexMap, _already_loaded: IndexMap>>, diff --git a/crates/shirabe/src/repository/installed_filesystem_repository.rs b/crates/shirabe/src/repository/installed_filesystem_repository.rs index db1428a6..5c6fecf9 100644 --- a/crates/shirabe/src/repository/installed_filesystem_repository.rs +++ b/crates/shirabe/src/repository/installed_filesystem_repository.rs @@ -3,7 +3,7 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::json::JsonFile; use crate::package::BasePackage; @@ -124,7 +124,7 @@ impl RepositoryInterface for InstalledFilesystemRepository { } fn load_packages( &self, - _package_name_map: IndexMap>>, + _package_name_map: IndexMap>, _acceptable_stabilities: IndexMap, _stability_flags: IndexMap, _already_loaded: IndexMap>>, diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index 3163ed2d..5c9e0d72 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -2,9 +2,9 @@ use indexmap::IndexMap; use shirabe_php_shim::LogicException; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::MatchAllConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::package::BasePackage; use crate::package::Link; @@ -56,7 +56,7 @@ impl InstalledRepository { ) -> Vec> { let name = name.to_lowercase(); - let constraint: Option> = match constraint { + let constraint: Option = match constraint { None => None, Some(FindPackageConstraint::Constraint(c)) => Some(c), Some(FindPackageConstraint::String(s)) => { @@ -70,10 +70,14 @@ impl InstalledRepository { 'candidates: for candidate in repo.get_packages() { if name == candidate.get_name() { if constraint.is_none() - || constraint - .as_ref() - .unwrap() - .matches(&Constraint::new("==", candidate.get_version())) + || constraint.as_ref().unwrap().matches( + &SimpleConstraint::new( + "==".to_string(), + candidate.get_version().to_string(), + None, + ) + .into(), + ) { matches.push(candidate); } @@ -107,7 +111,7 @@ impl InstalledRepository { pub fn get_dependents( &self, needle: NeedleInput, - constraint: Option>, + constraint: Option, invert: bool, recurse: bool, packages_found: Option>, @@ -142,9 +146,7 @@ impl InstalledRepository { for needle in &needles_snapshot { if link.get_source() == needle.as_str() { if constraint.is_none() - || link - .get_constraint() - .matches(constraint.as_ref().unwrap().as_ref()) + || link.get_constraint().matches(constraint.as_ref().unwrap()) { if packages_in_tree.contains(&link.get_target().to_string()) { results.push(DependentsEntry( @@ -187,9 +189,9 @@ impl InstalledRepository { for link in links.values() { for needle in &needles { if link.get_target() == needle.as_str() { - let matches_constraint = constraint.as_ref().map_or(true, |c| { - link.get_constraint().matches(c.as_ref()) == !invert - }); + let matches_constraint = constraint + .as_ref() + .map_or(true, |c| link.get_constraint().matches(c) == !invert); if constraint.is_none() || matches_constraint { if packages_in_tree.contains(&link.get_source().to_string()) { results.push(DependentsEntry( @@ -224,8 +226,12 @@ impl InstalledRepository { if invert && needles.contains(&package.get_name().to_string()) { for link in package.get_conflicts().values() { for pkg in self.find_packages(link.get_target(), None) { - let version = Constraint::new("=", pkg.get_version()); - if link.get_constraint().matches(&version) == invert { + let version = SimpleConstraint::new( + "=".to_string(), + pkg.get_version().to_string(), + None, + ); + if link.get_constraint().matches(&version.into()) == invert { results.push(DependentsEntry(package.clone_box(), link.clone(), None)); } } @@ -235,8 +241,12 @@ impl InstalledRepository { for link in package.get_conflicts().values() { if needles.contains(&link.get_target().to_string()) { for pkg in self.find_packages(link.get_target(), None) { - let version = Constraint::new("=", pkg.get_version()); - if link.get_constraint().matches(&version) == invert { + let version = SimpleConstraint::new( + "=".to_string(), + pkg.get_version().to_string(), + None, + ); + if link.get_constraint().matches(&version.into()) == invert { results.push(DependentsEntry(package.clone_box(), link.clone(), None)); } } @@ -246,19 +256,21 @@ impl InstalledRepository { if invert && constraint.is_some() && needles.contains(&package.get_name().to_string()) - && constraint - .as_ref() - .unwrap() - .matches(&Constraint::new("=", package.get_version())) + && constraint.as_ref().unwrap().matches( + &SimpleConstraint::new( + "=".to_string(), + package.get_version().to_string(), + None, + ) + .into(), + ) { 'requires: for link in package.get_requires().values() { if PlatformRepository::is_platform_package(link.get_target()) { if self .find_package( link.get_target(), - FindPackageConstraint::Constraint( - link.get_constraint().clone_box(), - ), + FindPackageConstraint::Constraint(link.get_constraint().clone()), ) .is_some() { @@ -278,7 +290,7 @@ impl InstalledRepository { Link::new( package.get_name().to_string(), link.get_target().to_string(), - Box::new(MatchAllConstraint::new()), + MatchAllConstraint::new(None).into(), Some(Link::TYPE_REQUIRE.to_string()), Some(format!( "{} {}", @@ -297,8 +309,12 @@ impl InstalledRepository { continue; } - let mut version: Box = - Box::new(Constraint::new("=", pkg.get_version())); + let mut version: AnyConstraint = SimpleConstraint::new( + "=".to_string(), + pkg.get_version().to_string(), + None, + ) + .into(); if link.get_target() != pkg.get_name() { let mut replaces_and_provides: IndexMap = @@ -308,13 +324,13 @@ impl InstalledRepository { } for prov in replaces_and_provides.values() { if link.get_target() == prov.get_target() { - version = prov.get_constraint().clone_box(); + version = prov.get_constraint().clone(); break; } } } - if !link.get_constraint().matches(version.as_ref()) { + if !link.get_constraint().matches(&version) { if let Some(root_pkg) = root_package.as_ref() { let mut root_reqs: IndexMap = root_pkg.get_requires(); for (k, v) in root_pkg.get_dev_requires() { @@ -350,7 +366,7 @@ impl InstalledRepository { Link::new( root_pkg.get_name().to_string(), link.get_target().to_string(), - Box::new(MatchAllConstraint::new()), + MatchAllConstraint::new(None).into(), Some(Link::TYPE_DOES_NOT_REQUIRE.to_string()), Some(format!( "but {} is installed", @@ -446,7 +462,7 @@ impl RepositoryInterface for InstalledRepository { fn load_packages( &self, - package_name_map: IndexMap>>, + package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, diff --git a/crates/shirabe/src/repository/lock_array_repository.rs b/crates/shirabe/src/repository/lock_array_repository.rs index 295d9822..57abe56f 100644 --- a/crates/shirabe/src/repository/lock_array_repository.rs +++ b/crates/shirabe/src/repository/lock_array_repository.rs @@ -9,7 +9,7 @@ use crate::repository::{ }; use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub struct LockArrayRepository { @@ -61,7 +61,7 @@ impl RepositoryInterface for LockArrayRepository { fn load_packages( &self, - package_name_map: IndexMap>>, + package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, diff --git a/crates/shirabe/src/repository/package_repository.rs b/crates/shirabe/src/repository/package_repository.rs index 6e8186ce..93c7e311 100644 --- a/crates/shirabe/src/repository/package_repository.rs +++ b/crates/shirabe/src/repository/package_repository.rs @@ -13,7 +13,7 @@ use crate::repository::{ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use shirabe_php_shim::{Exception, PhpMixed, RuntimeException, var_export}; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub struct PackageRepository { @@ -91,7 +91,7 @@ impl AdvisoryProviderInterface for PackageRepository { fn get_security_advisories( &self, - package_constraint_map: IndexMap>, + package_constraint_map: IndexMap, allow_partial_advisories: bool, ) -> anyhow::Result { let parser = VersionParser::new(); diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs index 8494e250..0b3ccb14 100644 --- a/crates/shirabe/src/repository/platform_repository.rs +++ b/crates/shirabe/src/repository/platform_repository.rs @@ -11,7 +11,8 @@ use shirabe_php_shim::{ array_slice_strs, explode, get_class, implode, in_array, is_string, sprintf, str_replace, str_starts_with, strpos, strtolower, var_export, }; -use shirabe_semver::constraint::Constraint; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::composer; use crate::composer::ComposerHandle; @@ -1759,7 +1760,7 @@ impl PlatformRepository { Link::new( "ext-uuid".to_string(), "lib-uuid".to_string(), - Box::new(Constraint::new("=", &version)), + SimpleConstraint::new("=".to_string(), version.to_string(), None).into(), Some(Link::TYPE_REPLACE.to_string()), Some(ext.get_pretty_version().to_string()), ), @@ -1824,7 +1825,7 @@ impl PlatformRepository { Link::new( format!("lib-{}", name), format!("lib-{}", replace_lower), - Box::new(Constraint::new("=", &version)), + SimpleConstraint::new("=".to_string(), version.to_string(), None).into(), Some(Link::TYPE_REPLACE.to_string()), Some(lib.get_pretty_version().to_string()), ), @@ -1838,7 +1839,7 @@ impl PlatformRepository { Link::new( format!("lib-{}", name), format!("lib-{}", provide_lower), - Box::new(Constraint::new("=", &version)), + SimpleConstraint::new("=".to_string(), version.to_string(), None).into(), Some(Link::TYPE_PROVIDE.to_string()), Some(lib.get_pretty_version().to_string()), ), @@ -1962,10 +1963,7 @@ impl crate::repository::RepositoryInterface for PlatformRepository { fn load_packages( &self, - package_name_map: IndexMap< - String, - Option>, - >, + package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, diff --git a/crates/shirabe/src/repository/repository_interface.rs b/crates/shirabe/src/repository/repository_interface.rs index d18951b0..4bd1f3e5 100644 --- a/crates/shirabe/src/repository/repository_interface.rs +++ b/crates/shirabe/src/repository/repository_interface.rs @@ -5,18 +5,18 @@ use crate::package::PackageInterface; use crate::repository::AdvisoryProviderInterface; use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; pub enum FindPackageConstraint { String(String), - Constraint(Box), + Constraint(AnyConstraint), } impl Clone for FindPackageConstraint { fn clone(&self) -> Self { match self { Self::String(s) => Self::String(s.clone()), - Self::Constraint(c) => Self::Constraint(c.clone_box()), + Self::Constraint(c) => Self::Constraint(c.clone()), } } } @@ -71,7 +71,7 @@ pub trait RepositoryInterface: Countable + std::fmt::Debug { fn load_packages( &self, - package_name_map: IndexMap>>, + package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, diff --git a/crates/shirabe/src/repository/repository_manager.rs b/crates/shirabe/src/repository/repository_manager.rs index 10e3e37e..e85312a5 100644 --- a/crates/shirabe/src/repository/repository_manager.rs +++ b/crates/shirabe/src/repository/repository_manager.rs @@ -2,7 +2,7 @@ use indexmap::IndexMap; use shirabe_php_shim::{InvalidArgumentException, PhpMixed, json_encode}; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::config::Config; use crate::event_dispatcher::EventDispatcher; @@ -51,12 +51,12 @@ impl RepositoryManager { pub fn find_package( &self, name: &str, - constraint: &dyn ConstraintInterface, + constraint: &AnyConstraint, ) -> Option> { for repository in &self.repositories { if let Some(package) = repository.find_package( name, - crate::repository::FindPackageConstraint::Constraint(constraint.clone_box()), + crate::repository::FindPackageConstraint::Constraint(constraint.clone()), ) { return Some(package.clone_package_box()); } @@ -67,14 +67,14 @@ impl RepositoryManager { pub fn find_packages( &self, name: &str, - constraint: &dyn ConstraintInterface, + constraint: &AnyConstraint, ) -> Vec> { let mut packages: Vec> = vec![]; for repository in self.get_repositories() { for p in repository.find_packages( name, Some(crate::repository::FindPackageConstraint::Constraint( - constraint.clone_box(), + constraint.clone(), )), ) { packages.push(p.clone_package_box()); diff --git a/crates/shirabe/src/repository/repository_set.rs b/crates/shirabe/src/repository/repository_set.rs index 84b24248..84159d40 100644 --- a/crates/shirabe/src/repository/repository_set.rs +++ b/crates/shirabe/src/repository/repository_set.rs @@ -8,10 +8,10 @@ use shirabe_php_shim::{ LogicException, PhpMixed, RuntimeException, array_merge, array_merge_recursive, ksort, strtolower, }; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::MatchAllConstraint; use shirabe_semver::constraint::MultiConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::advisory::PartialSecurityAdvisory; use crate::advisory::SecurityAdvisory; @@ -79,10 +79,10 @@ pub struct RepositorySet { /// @var ConstraintInterface[] /// @phpstan-var array - pub(crate) root_requires: IndexMap>, + pub(crate) root_requires: IndexMap, /// @var array - pub(crate) temporary_constraints: IndexMap>, + pub(crate) temporary_constraints: IndexMap, /// @var bool locked: bool, @@ -115,8 +115,8 @@ impl RepositorySet { stability_flags: IndexMap, root_aliases: Vec, root_references: IndexMap, - mut root_requires: IndexMap>, - temporary_constraints: IndexMap>, + mut root_requires: IndexMap, + temporary_constraints: IndexMap, ) -> Self { let root_aliases = Self::get_root_aliases_per_package(root_aliases); @@ -156,12 +156,12 @@ impl RepositorySet { /// @return ConstraintInterface[] an array of package name => constraint from the root package, platform requirements excluded /// @phpstan-return array - pub fn get_root_requires(&self) -> &IndexMap> { + pub fn get_root_requires(&self) -> &IndexMap { &self.root_requires } /// @return array Runtime temporary constraints that will be used to filter packages - pub fn get_temporary_constraints(&self) -> &IndexMap> { + pub fn get_temporary_constraints(&self) -> &IndexMap { &self.temporary_constraints } @@ -208,7 +208,7 @@ impl RepositorySet { pub fn find_packages( &self, name: &str, - constraint: Option>, + constraint: Option, flags: i64, ) -> Vec> { let ignore_stability = (flags & Self::ALLOW_UNACCEPTABLE_STABILITIES) != 0; @@ -220,15 +220,14 @@ impl RepositorySet { // PHP: $repository->findPackages($name, $constraint) ?: [] let constraint_clone = constraint .as_ref() - .map(|c| FindPackageConstraint::Constraint(c.clone_box())); + .map(|c| FindPackageConstraint::Constraint(c.clone())); let found = repository.find_packages(name, constraint_clone); packages.push(found); } } else { 'outer: for repository in &self.repositories { - let mut name_map: IndexMap>> = - IndexMap::new(); - name_map.insert(name.to_string(), constraint.as_ref().map(|c| c.clone_box())); + let mut name_map: IndexMap> = IndexMap::new(); + name_map.insert(name.to_string(), constraint.as_ref().map(|c| c.clone())); let acceptable = if ignore_stability { // PHP: BasePackage::STABILITIES crate::package::STABILITIES @@ -290,9 +289,9 @@ impl RepositorySet { allow_partial_advisories: bool, ignore_unreachable: bool, ) -> Result { - let mut map: IndexMap> = IndexMap::new(); + let mut map: IndexMap = IndexMap::new(); for name in &package_names { - map.insert(name.clone(), Box::new(MatchAllConstraint::new())); + map.insert(name.clone(), MatchAllConstraint::new(None).into()); } let mut unreachable_repos: Vec = vec![]; @@ -317,7 +316,7 @@ impl RepositorySet { allow_partial_advisories: bool, ignore_unreachable: bool, ) -> Result { - let mut map: IndexMap> = IndexMap::new(); + let mut map: IndexMap = IndexMap::new(); for package in packages { // ignore root alias versions as they are not actual package versions and should not matter when it comes to vulnerabilities if let Some(alias) = package.as_any().downcast_ref::() { @@ -327,20 +326,29 @@ impl RepositorySet { } let name = package.get_name().to_string(); if map.contains_key(&name) { - // TODO(phase-b): MultiConstraint::new signature let existing = map.shift_remove(&name).unwrap(); map.insert( name, - Box::new(MultiConstraint::new( + MultiConstraint::new( vec![ - Box::new(Constraint::new("=", package.get_version())), + AnyConstraint::Simple(SimpleConstraint::new( + "=".to_string(), + package.get_version().to_string(), + None, + )), existing, ], false, - )), + None, + ) + .into(), ); } else { - map.insert(name, Box::new(Constraint::new("=", package.get_version()))); + map.insert( + name, + SimpleConstraint::new("=".to_string(), package.get_version().to_string(), None) + .into(), + ); } } @@ -363,7 +371,7 @@ impl RepositorySet { /// @return ($allowPartialAdvisories is true ? array> : array>) fn get_security_advisories_for_constraints( &self, - package_constraint_map: IndexMap>, + package_constraint_map: IndexMap, allow_partial_advisories: bool, ignore_unreachable: bool, unreachable_repos: &mut Vec, diff --git a/crates/shirabe/src/repository/root_package_repository.rs b/crates/shirabe/src/repository/root_package_repository.rs index 62132910..1487f3e3 100644 --- a/crates/shirabe/src/repository/root_package_repository.rs +++ b/crates/shirabe/src/repository/root_package_repository.rs @@ -61,10 +61,7 @@ impl RepositoryInterface for RootPackageRepository { fn load_packages( &self, - package_name_map: IndexMap< - String, - Option>, - >, + package_name_map: IndexMap>, acceptable_stabilities: IndexMap, stability_flags: IndexMap, already_loaded: IndexMap>>, diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs index 05dd329f..1ae7e401 100644 --- a/crates/shirabe/src/repository/vcs_repository.rs +++ b/crates/shirabe/src/repository/vcs_repository.rs @@ -8,7 +8,8 @@ use shirabe_php_shim::{ InvalidArgumentException, PhpMixed, array_search_mixed, count, get_class, in_array, str_replace, strpos, }; -use shirabe_semver::constraint::Constraint; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::config::Config; use crate::downloader::TransportException; @@ -514,9 +515,14 @@ impl VcsRepository { }); if let Some(existing_package) = self.inner.find_package( &tag_package_name, - crate::repository::FindPackageConstraint::Constraint(Box::new( - Constraint::new("=", &version_normalized), - )), + crate::repository::FindPackageConstraint::Constraint( + SimpleConstraint::new( + "=".to_string(), + version_normalized.to_string(), + None, + ) + .into(), + ), ) { if is_very_verbose { self.io.write_error(&format!( @@ -949,10 +955,10 @@ impl VcsRepository { .to_string(); if let Some(existing_package) = self.inner.find_package( &name, - crate::repository::FindPackageConstraint::Constraint(Box::new(Constraint::new( - "=", - &version_normalized, - ))), + crate::repository::FindPackageConstraint::Constraint( + SimpleConstraint::new("=".to_string(), version_normalized.to_string(), None) + .into(), + ), ) { if is_very_verbose { self.io.write_error(&format!( -- cgit v1.3.1-4-g156e