diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-23 23:14:52 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-23 23:15:14 +0900 |
| commit | dbdecaf5a1c54a876b7ee0153d58dd39b1080f97 (patch) | |
| tree | f13f2ced03c803dcbc42a5672458b3cb19ff0f30 /crates/shirabe/src/repository | |
| parent | f5b987a00712211b7ce56300851182bda904e97b (diff) | |
| download | php-shirabe-dbdecaf5a1c54a876b7ee0153d58dd39b1080f97.tar.gz php-shirabe-dbdecaf5a1c54a876b7ee0153d58dd39b1080f97.tar.zst php-shirabe-dbdecaf5a1c54a876b7ee0153d58dd39b1080f97.zip | |
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) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/repository')
16 files changed, 198 insertions, 166 deletions
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<String, Box<dyn ConstraintInterface>>, + package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult>; } 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<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -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<Box<dyn BasePackage>> { let name = strtolower(name); - let constraint: Box<dyn ConstraintInterface> = 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<Box<dyn ConstraintInterface>> = match constraint { + let constraint: Option<AnyConstraint> = 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<dyn ConstraintInterface> = 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<Box<dyn BasePackage>> = 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<String, Option<Box<dyn ConstraintInterface>>> = IndexMap::new(); + let mut map: IndexMap<String, Option<AnyConstraint>> = 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<Box<dyn BasePackage>> = 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<Box<dyn ConstraintInterface>> = match constraint { + let constraint: Option<AnyConstraint> = 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<Box<dyn BasePackage>> = 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<String, Option<Box<dyn ConstraintInterface>>> = IndexMap::new(); + let mut map: IndexMap<String, Option<AnyConstraint>> = 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<Box<dyn BasePackage>> = 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<Box<dyn BasePackage>>, - 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<Box<dyn BasePackage>> = 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<String, Option<Box<dyn ConstraintInterface>>> = - IndexMap::new(); + let mut package_map: IndexMap<String, Option<AnyConstraint>> = IndexMap::new(); for name in available_packages.values() { - package_map.insert( - name.clone(), - Some( - Box::new(MatchAllConstraint::new()) as Box<dyn ConstraintInterface> - ), - ); + 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<String, Option<Box<dyn ConstraintInterface>>>, + mut package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -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<String, Box<dyn ConstraintInterface>>, + mut package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult> { self.load_root_server_file(Some(600))?; @@ -1059,7 +1057,7 @@ impl ComposerRepository { let repo_name = self.get_repo_name(); let create = |data: &IndexMap<String, PhpMixed>, name: &str, - package_constraint_map: &IndexMap<String, Box<dyn ConstraintInterface>>| + package_constraint_map: &IndexMap<String, AnyConstraint>| -> anyhow::Result<Option<PartialOrSecurityAdvisory>> { 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<String, Option<Box<dyn ConstraintInterface>>>, + mut package_names: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: Option<&IndexMap<String, i64>>, stability_flags: Option<&IndexMap<String, i64>>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -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<Box<dyn ConstraintInterface>>)> = package_names + let names_iter: Vec<(String, Option<AnyConstraint>)> = package_names .iter() .map(|(k, v)| { - let cloned: Option<Box<dyn ConstraintInterface>> = - v.as_ref().map(|c| dyn_clone_constraint(&**c)); + let cloned: Option<AnyConstraint> = 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<String, PhpMixed>, acceptable_stabilities: Option<&IndexMap<String, i64>>, @@ -2110,7 +2107,7 @@ impl ComposerRepository { } fn is_version_acceptable_static( - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, name: &str, version_data: &IndexMap<String, PhpMixed>, acceptable_stabilities: Option<&IndexMap<String, i64>>, @@ -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<String, PhpMixed>, acceptable_stabilities: Option<&IndexMap<String, i64>>, @@ -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<dyn BasePackage> { todo!() } - -fn dyn_clone_constraint(_c: &dyn ConstraintInterface) -> Box<dyn ConstraintInterface> { - 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<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -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<String, Option<Box<dyn ConstraintInterface>>> = - package_name_map - .iter() - .map(|(k, v)| (k.clone(), v.as_ref().map(|c| c.clone_box()))) - .collect(); + let name_map_cloned: IndexMap<String, Option<AnyConstraint>> = package_name_map + .iter() + .map(|(k, v)| (k.clone(), v.as_ref().map(|c| c.clone()))) + .collect(); let already_loaded_cloned: IndexMap< String, IndexMap<String, Box<dyn PackageInterface>>, 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<String, Option<Box<dyn ConstraintInterface>>>, + mut package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -272,7 +272,7 @@ impl AdvisoryProviderInterface for FilterRepository { fn get_security_advisories( &self, - mut package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, + mut package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult> { 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<String, Option<Box<dyn ConstraintInterface>>>, + _package_name_map: IndexMap<String, Option<AnyConstraint>>, _acceptable_stabilities: IndexMap<String, i64>, _stability_flags: IndexMap<String, i64>, _already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, 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<String, Option<Box<dyn ConstraintInterface>>>, + _package_name_map: IndexMap<String, Option<AnyConstraint>>, _acceptable_stabilities: IndexMap<String, i64>, _stability_flags: IndexMap<String, i64>, _already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, 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<Box<dyn BasePackage>> { let name = name.to_lowercase(); - let constraint: Option<Box<dyn ConstraintInterface>> = match constraint { + let constraint: Option<AnyConstraint> = 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<Box<dyn ConstraintInterface>>, + constraint: Option<AnyConstraint>, invert: bool, recurse: bool, packages_found: Option<Vec<String>>, @@ -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<dyn ConstraintInterface> = - 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<String, Link> = @@ -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<String, Link> = 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<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, 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<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, 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<String, Box<dyn ConstraintInterface>>, + package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult> { 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<Box<dyn shirabe_semver::constraint::ConstraintInterface>>, - >, + package_name_map: IndexMap<String, Option<shirabe_semver::constraint::AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, 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<dyn ConstraintInterface>), + 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<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, 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<Box<dyn PackageInterface>> { 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<Box<dyn PackageInterface>> { let mut packages: Vec<Box<dyn PackageInterface>> = 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<string, ConstraintInterface> - pub(crate) root_requires: IndexMap<String, Box<dyn ConstraintInterface>>, + pub(crate) root_requires: IndexMap<String, AnyConstraint>, /// @var array<string, ConstraintInterface> - pub(crate) temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>, + pub(crate) temporary_constraints: IndexMap<String, AnyConstraint>, /// @var bool locked: bool, @@ -115,8 +115,8 @@ impl RepositorySet { stability_flags: IndexMap<String, i64>, root_aliases: Vec<RootAliasInput>, root_references: IndexMap<String, String>, - mut root_requires: IndexMap<String, Box<dyn ConstraintInterface>>, - temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>, + mut root_requires: IndexMap<String, AnyConstraint>, + temporary_constraints: IndexMap<String, AnyConstraint>, ) -> 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<string, ConstraintInterface> - pub fn get_root_requires(&self) -> &IndexMap<String, Box<dyn ConstraintInterface>> { + pub fn get_root_requires(&self) -> &IndexMap<String, AnyConstraint> { &self.root_requires } /// @return array<string, ConstraintInterface> Runtime temporary constraints that will be used to filter packages - pub fn get_temporary_constraints(&self) -> &IndexMap<String, Box<dyn ConstraintInterface>> { + pub fn get_temporary_constraints(&self) -> &IndexMap<String, AnyConstraint> { &self.temporary_constraints } @@ -208,7 +208,7 @@ impl RepositorySet { pub fn find_packages( &self, name: &str, - constraint: Option<Box<dyn ConstraintInterface>>, + constraint: Option<AnyConstraint>, flags: i64, ) -> Vec<Box<dyn BasePackage>> { 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<String, Option<Box<dyn ConstraintInterface>>> = - IndexMap::new(); - name_map.insert(name.to_string(), constraint.as_ref().map(|c| c.clone_box())); + let mut name_map: IndexMap<String, Option<AnyConstraint>> = 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<SecurityAdvisoriesResult> { - let mut map: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let mut map: IndexMap<String, AnyConstraint> = 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<String> = vec![]; @@ -317,7 +316,7 @@ impl RepositorySet { allow_partial_advisories: bool, ignore_unreachable: bool, ) -> Result<SecurityAdvisoriesResult> { - let mut map: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let mut map: IndexMap<String, AnyConstraint> = 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::<AliasPackage>() { @@ -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<string, array<PartialSecurityAdvisory|SecurityAdvisory>> : array<string, array<SecurityAdvisory>>) fn get_security_advisories_for_constraints( &self, - package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, + package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ignore_unreachable: bool, unreachable_repos: &mut Vec<String>, 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<Box<dyn shirabe_semver::constraint::ConstraintInterface>>, - >, + package_name_map: IndexMap<String, Option<shirabe_semver::constraint::AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, 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!( |
