aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe-external-packages/src/composer/semver/compiling_matcher.rs8
-rw-r--r--crates/shirabe-external-packages/src/composer/semver/intervals.rs14
-rw-r--r--crates/shirabe-semver/src/comparator.rs9
-rw-r--r--crates/shirabe-semver/src/compiling_matcher.rs23
-rw-r--r--crates/shirabe-semver/src/constraint.rs8
-rw-r--r--crates/shirabe-semver/src/constraint/any_constraint.rs169
-rw-r--r--crates/shirabe-semver/src/constraint/constraint_interface.rs43
-rw-r--r--crates/shirabe-semver/src/constraint/match_all_constraint.rs55
-rw-r--r--crates/shirabe-semver/src/constraint/match_none_constraint.rs41
-rw-r--r--crates/shirabe-semver/src/constraint/multi_constraint.rs196
-rw-r--r--crates/shirabe-semver/src/constraint/simple_constraint.rs (renamed from crates/shirabe-semver/src/constraint/constraint.rs)118
-rw-r--r--crates/shirabe-semver/src/interval.rs25
-rw-r--r--crates/shirabe-semver/src/intervals.rs249
-rw-r--r--crates/shirabe-semver/src/semver.rs10
-rw-r--r--crates/shirabe-semver/src/version_parser.rs83
-rw-r--r--crates/shirabe/src/advisory/ignored_security_advisory.rs4
-rw-r--r--crates/shirabe/src/advisory/partial_security_advisory.rs39
-rw-r--r--crates/shirabe/src/advisory/security_advisory.rs10
-rw-r--r--crates/shirabe/src/autoload/autoload_generator.rs6
-rw-r--r--crates/shirabe/src/command/archive_command.rs10
-rw-r--r--crates/shirabe/src/command/base_dependency_command.rs10
-rw-r--r--crates/shirabe/src/command/check_platform_reqs_command.rs23
-rw-r--r--crates/shirabe/src/command/fund_command.rs7
-rw-r--r--crates/shirabe/src/command/package_discovery_trait.rs9
-rw-r--r--crates/shirabe/src/command/show_command.rs6
-rw-r--r--crates/shirabe/src/command/update_command.rs7
-rw-r--r--crates/shirabe/src/dependency_resolver/default_policy.rs13
-rw-r--r--crates/shirabe/src/dependency_resolver/pool.rs38
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_builder.rs88
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_optimizer.rs84
-rw-r--r--crates/shirabe/src/dependency_resolver/problem.rs105
-rw-r--r--crates/shirabe/src/dependency_resolver/request.rs10
-rw-r--r--crates/shirabe/src/dependency_resolver/rule.rs36
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_generator.rs18
-rw-r--r--crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs7
-rw-r--r--crates/shirabe/src/dependency_resolver/solver.rs9
-rw-r--r--crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs24
-rw-r--r--crates/shirabe/src/installed_versions.rs2
-rw-r--r--crates/shirabe/src/installer.rs64
-rw-r--r--crates/shirabe/src/package/alias_package.rs27
-rw-r--r--crates/shirabe/src/package/link.rs14
-rw-r--r--crates/shirabe/src/package/loader/array_loader.rs4
-rw-r--r--crates/shirabe/src/package/loader/validating_array_loader.rs22
-rw-r--r--crates/shirabe/src/package/locker.rs2
-rw-r--r--crates/shirabe/src/package/version/version_bumper.rs8
-rw-r--r--crates/shirabe/src/package/version/version_parser.rs25
-rw-r--r--crates/shirabe/src/package/version/version_selector.rs25
-rw-r--r--crates/shirabe/src/plugin/plugin_manager.rs17
-rw-r--r--crates/shirabe/src/repository/advisory_provider_interface.rs4
-rw-r--r--crates/shirabe/src/repository/array_repository.rs43
-rw-r--r--crates/shirabe/src/repository/composer_repository.rs91
-rw-r--r--crates/shirabe/src/repository/composite_repository.rs13
-rw-r--r--crates/shirabe/src/repository/filter_repository.rs6
-rw-r--r--crates/shirabe/src/repository/installed_array_repository.rs4
-rw-r--r--crates/shirabe/src/repository/installed_filesystem_repository.rs4
-rw-r--r--crates/shirabe/src/repository/installed_repository.rs80
-rw-r--r--crates/shirabe/src/repository/lock_array_repository.rs4
-rw-r--r--crates/shirabe/src/repository/package_repository.rs4
-rw-r--r--crates/shirabe/src/repository/platform_repository.rs14
-rw-r--r--crates/shirabe/src/repository/repository_interface.rs8
-rw-r--r--crates/shirabe/src/repository/repository_manager.rs10
-rw-r--r--crates/shirabe/src/repository/repository_set.rs52
-rw-r--r--crates/shirabe/src/repository/root_package_repository.rs5
-rw-r--r--crates/shirabe/src/repository/vcs_repository.rs22
-rw-r--r--crates/shirabe/src/util/http_downloader.rs25
65 files changed, 1134 insertions, 1079 deletions
diff --git a/crates/shirabe-external-packages/src/composer/semver/compiling_matcher.rs b/crates/shirabe-external-packages/src/composer/semver/compiling_matcher.rs
index 246c4e5..b075ba7 100644
--- a/crates/shirabe-external-packages/src/composer/semver/compiling_matcher.rs
+++ b/crates/shirabe-external-packages/src/composer/semver/compiling_matcher.rs
@@ -1,18 +1,18 @@
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
#[derive(Debug)]
pub struct CompilingMatcher;
impl CompilingMatcher {
- pub fn r#match(_constraint: &dyn ConstraintInterface, _package: &dyn std::any::Any) -> bool {
+ pub fn r#match(_constraint: &AnyConstraint, _package: &dyn std::any::Any) -> bool {
todo!()
}
- pub fn matches(_constraint: &dyn ConstraintInterface, _operator: i64, _version: &str) -> bool {
+ pub fn matches(_constraint: &AnyConstraint, _operator: i64, _version: &str) -> bool {
todo!()
}
- pub fn match_(_constraint: &dyn ConstraintInterface, _operator: i64, _version: &str) -> bool {
+ pub fn match_(_constraint: &AnyConstraint, _operator: i64, _version: &str) -> bool {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/composer/semver/intervals.rs b/crates/shirabe-external-packages/src/composer/semver/intervals.rs
index ff04cd8..bf8a74f 100644
--- a/crates/shirabe-external-packages/src/composer/semver/intervals.rs
+++ b/crates/shirabe-external-packages/src/composer/semver/intervals.rs
@@ -1,28 +1,26 @@
use shirabe_php_shim::PhpMixed;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
#[derive(Debug)]
pub struct Intervals;
impl Intervals {
pub fn is_subset_of(
- _constraint_a: &dyn ConstraintInterface,
- _constraint_b: &dyn ConstraintInterface,
+ _constraint_a: &AnyConstraint,
+ _constraint_b: &AnyConstraint,
) -> anyhow::Result<bool> {
todo!()
}
- pub fn compact_constraint(
- _constraint: Box<dyn ConstraintInterface>,
- ) -> Box<dyn ConstraintInterface> {
+ pub fn compact_constraint(_constraint: AnyConstraint) -> AnyConstraint {
todo!()
}
- pub fn compact(_constraint: &dyn ConstraintInterface) -> Box<dyn ConstraintInterface> {
+ pub fn compact(_constraint: &AnyConstraint) -> AnyConstraint {
todo!()
}
- pub fn get(_constraint: &dyn ConstraintInterface) -> anyhow::Result<PhpMixed> {
+ pub fn get(_constraint: &AnyConstraint) -> anyhow::Result<PhpMixed> {
todo!()
}
diff --git a/crates/shirabe-semver/src/comparator.rs b/crates/shirabe-semver/src/comparator.rs
index 6db06d4..36a4142 100644
--- a/crates/shirabe-semver/src/comparator.rs
+++ b/crates/shirabe-semver/src/comparator.rs
@@ -1,6 +1,6 @@
//! ref: composer/vendor/composer/semver/src/Comparator.php
-use crate::constraint::Constraint;
+use crate::constraint::SimpleConstraint;
pub struct Comparator;
@@ -30,7 +30,10 @@ impl Comparator {
}
pub fn compare(version1: String, operator: String, version2: String) -> bool {
- let constraint = Constraint::new(operator, version2);
- constraint.match_specific(&Constraint::new("==".to_string(), version1), true)
+ let constraint = SimpleConstraint::new(operator, version2, None);
+ constraint.match_specific(
+ &SimpleConstraint::new("==".to_string(), version1, None),
+ true,
+ )
}
}
diff --git a/crates/shirabe-semver/src/compiling_matcher.rs b/crates/shirabe-semver/src/compiling_matcher.rs
index 737647f..d7e203e 100644
--- a/crates/shirabe-semver/src/compiling_matcher.rs
+++ b/crates/shirabe-semver/src/compiling_matcher.rs
@@ -5,8 +5,8 @@ use std::sync::OnceLock;
use indexmap::IndexMap;
-use crate::constraint::Constraint;
-use crate::constraint::ConstraintInterface;
+use crate::constraint::AnyConstraint;
+use crate::constraint::SimpleConstraint;
static COMPILED_CHECKER_CACHE: OnceLock<
Mutex<IndexMap<String, Box<dyn Fn(String, bool) -> bool + Send + Sync>>>,
@@ -16,12 +16,12 @@ static RESULT_CACHE: OnceLock<Mutex<IndexMap<String, bool>>> = OnceLock::new();
// Rust does not support eval(), so the compiled checker path is always disabled.
// The COMPILED_CHECKER_CACHE is retained structurally but never populated.
static TRANS_OP_INT: &[(i64, &str)] = &[
- (Constraint::OP_EQ, Constraint::STR_OP_EQ),
- (Constraint::OP_LT, Constraint::STR_OP_LT),
- (Constraint::OP_LE, Constraint::STR_OP_LE),
- (Constraint::OP_GT, Constraint::STR_OP_GT),
- (Constraint::OP_GE, Constraint::STR_OP_GE),
- (Constraint::OP_NE, Constraint::STR_OP_NE),
+ (SimpleConstraint::OP_EQ, SimpleConstraint::STR_OP_EQ),
+ (SimpleConstraint::OP_LT, SimpleConstraint::STR_OP_LT),
+ (SimpleConstraint::OP_LE, SimpleConstraint::STR_OP_LE),
+ (SimpleConstraint::OP_GT, SimpleConstraint::STR_OP_GT),
+ (SimpleConstraint::OP_GE, SimpleConstraint::STR_OP_GE),
+ (SimpleConstraint::OP_NE, SimpleConstraint::STR_OP_NE),
];
pub struct CompilingMatcher;
@@ -41,8 +41,8 @@ impl CompilingMatcher {
Self::compiled_checker_cache().lock().unwrap().clear();
}
- pub fn r#match(constraint: &dyn ConstraintInterface, operator: i64, version: String) -> bool {
- let result_cache_key = format!("{}{};{}", operator, constraint.__to_string(), version);
+ pub fn r#match(constraint: &AnyConstraint, operator: i64, version: String) -> bool {
+ let result_cache_key = format!("{}{};{}", operator, constraint.to_string(), version);
{
let cache = Self::result_cache().lock().unwrap();
@@ -56,7 +56,8 @@ impl CompilingMatcher {
.find(|(op, _)| *op == operator)
.map(|(_, s)| *s)
.expect("unknown operator");
- let result = constraint.matches(&Constraint::new(trans_op.to_string(), version));
+ let result =
+ constraint.matches(&SimpleConstraint::new(trans_op.to_string(), version, None).into());
Self::result_cache()
.lock()
diff --git a/crates/shirabe-semver/src/constraint.rs b/crates/shirabe-semver/src/constraint.rs
index 6a57a57..75c15b6 100644
--- a/crates/shirabe-semver/src/constraint.rs
+++ b/crates/shirabe-semver/src/constraint.rs
@@ -1,13 +1,13 @@
+mod any_constraint;
mod bound;
-mod constraint;
-mod constraint_interface;
mod match_all_constraint;
mod match_none_constraint;
mod multi_constraint;
+mod simple_constraint;
+pub use any_constraint::*;
pub use bound::*;
-pub use constraint::*;
-pub use constraint_interface::*;
pub use match_all_constraint::*;
pub use match_none_constraint::*;
pub use multi_constraint::*;
+pub use simple_constraint::*;
diff --git a/crates/shirabe-semver/src/constraint/any_constraint.rs b/crates/shirabe-semver/src/constraint/any_constraint.rs
new file mode 100644
index 0000000..b61a36f
--- /dev/null
+++ b/crates/shirabe-semver/src/constraint/any_constraint.rs
@@ -0,0 +1,169 @@
+//! ref: composer/vendor/composer/semver/src/Constraint/ConstraintInterface.php
+
+use crate::constraint::Bound;
+use crate::constraint::MatchAllConstraint;
+use crate::constraint::MatchNoneConstraint;
+use crate::constraint::MultiConstraint;
+use crate::constraint::SimpleConstraint;
+
+/// Corresponds to PHP's `ConstraintInterface`.
+#[derive(Clone, Debug)]
+pub enum AnyConstraint {
+ Simple(SimpleConstraint),
+ Multi(MultiConstraint),
+ MatchAll(MatchAllConstraint),
+ MatchNone(MatchNoneConstraint),
+}
+
+impl AnyConstraint {
+ pub fn matches(&self, provider: &AnyConstraint) -> bool {
+ match self {
+ Self::MatchAll(_) => true,
+ Self::MatchNone(_) => false,
+ Self::Simple(c) => match provider.as_constraint() {
+ Some(p) => c.match_specific(p, false),
+ None => provider.matches(self),
+ },
+ Self::Multi(m) => {
+ if !m.conjunctive {
+ m.constraints.iter().any(|sub| provider.matches(sub))
+ } else if provider.is_disjunctive() {
+ provider.matches(self)
+ } else {
+ m.constraints.iter().all(|sub| provider.matches(sub))
+ }
+ }
+ }
+ }
+
+ pub fn compile(&self, other_operator: i64) -> String {
+ match self {
+ Self::Simple(c) => c.compile(other_operator),
+ Self::Multi(c) => c.compile(other_operator),
+ Self::MatchAll(c) => c.compile(other_operator),
+ Self::MatchNone(c) => c.compile(other_operator),
+ }
+ }
+
+ pub fn get_upper_bound(&self) -> Bound {
+ match self {
+ Self::Simple(c) => c.get_upper_bound(),
+ Self::Multi(c) => c.get_upper_bound(),
+ Self::MatchAll(c) => c.get_upper_bound(),
+ Self::MatchNone(c) => c.get_upper_bound(),
+ }
+ }
+
+ pub fn get_lower_bound(&self) -> Bound {
+ match self {
+ Self::Simple(c) => c.get_lower_bound(),
+ Self::Multi(c) => c.get_lower_bound(),
+ Self::MatchAll(c) => c.get_lower_bound(),
+ Self::MatchNone(c) => c.get_lower_bound(),
+ }
+ }
+
+ pub fn get_pretty_string(&self) -> String {
+ match self {
+ Self::Simple(c) => c.get_pretty_string(),
+ Self::Multi(c) => c.get_pretty_string(),
+ Self::MatchAll(c) => c.get_pretty_string(),
+ Self::MatchNone(c) => c.get_pretty_string(),
+ }
+ }
+
+ /// PHP `$c instanceof MultiConstraint && $c->isDisjunctive()`.
+ pub fn is_disjunctive(&self) -> bool {
+ matches!(self, Self::Multi(m) if !m.conjunctive)
+ }
+
+ /// PHP `$c instanceof Constraint`.
+ pub fn is_constraint(&self) -> bool {
+ matches!(self, Self::Simple(_))
+ }
+
+ pub fn get_operator(&self) -> &'static str {
+ match self {
+ Self::Simple(c) => c.get_operator(),
+ _ => "",
+ }
+ }
+
+ pub fn get_version(&self) -> &str {
+ match self {
+ Self::Simple(c) => c.get_version(),
+ _ => "",
+ }
+ }
+
+ pub fn as_constraint(&self) -> Option<&SimpleConstraint> {
+ match self {
+ Self::Simple(c) => Some(c),
+ _ => None,
+ }
+ }
+
+ pub fn as_multi_constraint(&self) -> Option<&MultiConstraint> {
+ match self {
+ Self::Multi(c) => Some(c),
+ _ => None,
+ }
+ }
+
+ pub fn is_match_all(&self) -> bool {
+ matches!(self, Self::MatchAll(_))
+ }
+
+ pub fn is_match_none(&self) -> bool {
+ matches!(self, Self::MatchNone(_))
+ }
+
+ /// PHP exposes `ConstraintInterface::setPrettyString()` and defaults the
+ /// pretty string to the constraint's string form when unset. This port takes
+ /// the pretty string at construction instead; this setter exists only so
+ /// `MultiConstraint::create()` can apply the pretty string PHP sets on its
+ /// (possibly polymorphic) result.
+ pub(crate) fn set_pretty_string(&mut self, pretty_string: Option<String>) {
+ match self {
+ Self::Simple(c) => c.pretty_string = pretty_string,
+ Self::Multi(c) => c.pretty_string = pretty_string,
+ Self::MatchAll(c) => c.pretty_string = pretty_string,
+ Self::MatchNone(c) => c.pretty_string = pretty_string,
+ }
+ }
+}
+
+impl From<SimpleConstraint> for AnyConstraint {
+ fn from(c: SimpleConstraint) -> Self {
+ Self::Simple(c)
+ }
+}
+
+impl From<MultiConstraint> for AnyConstraint {
+ fn from(c: MultiConstraint) -> Self {
+ Self::Multi(c)
+ }
+}
+
+impl From<MatchAllConstraint> for AnyConstraint {
+ fn from(c: MatchAllConstraint) -> Self {
+ Self::MatchAll(c)
+ }
+}
+
+impl From<MatchNoneConstraint> for AnyConstraint {
+ fn from(c: MatchNoneConstraint) -> Self {
+ Self::MatchNone(c)
+ }
+}
+
+impl std::fmt::Display for AnyConstraint {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::Simple(c) => write!(f, "{}", c),
+ Self::Multi(c) => write!(f, "{}", c),
+ Self::MatchAll(c) => write!(f, "{}", c),
+ Self::MatchNone(c) => write!(f, "{}", c),
+ }
+ }
+}
diff --git a/crates/shirabe-semver/src/constraint/constraint_interface.rs b/crates/shirabe-semver/src/constraint/constraint_interface.rs
deleted file mode 100644
index f04ed2a..0000000
--- a/crates/shirabe-semver/src/constraint/constraint_interface.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-//! ref: composer/vendor/composer/semver/src/Constraint/ConstraintInterface.php
-
-use crate::constraint::Bound;
-
-pub trait ConstraintInterface: std::fmt::Debug {
- fn matches(&self, provider: &dyn ConstraintInterface) -> bool;
-
- fn compile(&self, other_operator: i64) -> String;
-
- fn get_upper_bound(&self) -> Bound;
-
- fn get_lower_bound(&self) -> Bound;
-
- fn get_pretty_string(&self) -> String;
-
- fn set_pretty_string(&mut self, pretty_string: Option<String>);
-
- fn __to_string(&self) -> String;
-
- // Rust-specific helpers for instanceof checks in MultiConstraint::matches and optimizeConstraints.
- fn is_disjunctive(&self) -> bool {
- false
- }
-
- /// Rust-specific helper: PHP `$c instanceof Constraint` check.
- fn is_constraint(&self) -> bool {
- false
- }
-
- /// Rust-specific helper: PHP `$c->getOperator()`. Only meaningful when `is_constraint()` is true.
- fn get_operator(&self) -> &'static str {
- ""
- }
-
- /// Rust-specific helper: PHP `$c->getVersion()`. Only meaningful when `is_constraint()` is true.
- fn get_version(&self) -> &str {
- ""
- }
-
- fn clone_box(&self) -> Box<dyn ConstraintInterface>;
-
- fn as_any(&self) -> &dyn std::any::Any;
-}
diff --git a/crates/shirabe-semver/src/constraint/match_all_constraint.rs b/crates/shirabe-semver/src/constraint/match_all_constraint.rs
index b695ce2..8d4e870 100644
--- a/crates/shirabe-semver/src/constraint/match_all_constraint.rs
+++ b/crates/shirabe-semver/src/constraint/match_all_constraint.rs
@@ -1,68 +1,41 @@
//! ref: composer/vendor/composer/semver/src/Constraint/MatchAllConstraint.php
use crate::constraint::Bound;
-use crate::constraint::ConstraintInterface;
-#[derive(Debug)]
+#[derive(Debug, Clone, Default)]
pub struct MatchAllConstraint {
pub(crate) pretty_string: Option<String>,
}
impl MatchAllConstraint {
- pub fn new() -> Self {
- Self {
- pretty_string: None,
- }
+ pub fn new(pretty_string: Option<String>) -> Self {
+ Self { pretty_string }
}
-}
-
-impl Default for MatchAllConstraint {
- fn default() -> Self {
- Self::new()
- }
-}
-impl ConstraintInterface for MatchAllConstraint {
- fn matches(&self, _provider: &dyn ConstraintInterface) -> bool {
- true
- }
-
- fn compile(&self, _other_operator: i64) -> String {
+ pub fn compile(&self, _other_operator: i64) -> String {
"true".to_string()
}
- fn set_pretty_string(&mut self, pretty_string: Option<String>) {
- self.pretty_string = pretty_string;
- }
-
- fn get_pretty_string(&self) -> String {
+ pub fn get_pretty_string(&self) -> String {
if let Some(ref s) = self.pretty_string
&& !s.is_empty()
{
return s.clone();
}
- self.__to_string()
+ self.to_string()
}
- fn __to_string(&self) -> String {
- "*".to_string()
- }
-
- fn clone_box(&self) -> Box<dyn ConstraintInterface> {
- Box::new(MatchAllConstraint {
- pretty_string: self.pretty_string.clone(),
- })
- }
-
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn get_upper_bound(&self) -> Bound {
+ pub fn get_upper_bound(&self) -> Bound {
Bound::positive_infinity()
}
- fn get_lower_bound(&self) -> Bound {
+ pub fn get_lower_bound(&self) -> Bound {
Bound::zero()
}
}
+
+impl std::fmt::Display for MatchAllConstraint {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "*")
+ }
+}
diff --git a/crates/shirabe-semver/src/constraint/match_none_constraint.rs b/crates/shirabe-semver/src/constraint/match_none_constraint.rs
index 587058a..08cb319 100644
--- a/crates/shirabe-semver/src/constraint/match_none_constraint.rs
+++ b/crates/shirabe-semver/src/constraint/match_none_constraint.rs
@@ -1,54 +1,41 @@
//! ref: composer/vendor/composer/semver/src/Constraint/MatchNoneConstraint.php
use crate::constraint::Bound;
-use crate::constraint::ConstraintInterface;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct MatchNoneConstraint {
pub(crate) pretty_string: Option<String>,
}
-impl ConstraintInterface for MatchNoneConstraint {
- fn matches(&self, _provider: &dyn ConstraintInterface) -> bool {
- false
+impl MatchNoneConstraint {
+ pub fn new(pretty_string: Option<String>) -> Self {
+ Self { pretty_string }
}
- fn compile(&self, _other_operator: i64) -> String {
+ pub fn compile(&self, _other_operator: i64) -> String {
"false".to_string()
}
- fn set_pretty_string(&mut self, pretty_string: Option<String>) {
- self.pretty_string = pretty_string;
- }
-
- fn get_pretty_string(&self) -> String {
+ pub fn get_pretty_string(&self) -> String {
if let Some(ref s) = self.pretty_string
&& !s.is_empty()
{
return s.clone();
}
- self.__to_string()
+ self.to_string()
}
- fn __to_string(&self) -> String {
- "[]".to_string()
- }
-
- fn clone_box(&self) -> Box<dyn ConstraintInterface> {
- Box::new(MatchNoneConstraint {
- pretty_string: self.pretty_string.clone(),
- })
- }
-
- fn as_any(&self) -> &dyn std::any::Any {
- self
+ pub fn get_upper_bound(&self) -> Bound {
+ Bound::new("0.0.0.0-dev".to_string(), false)
}
- fn get_upper_bound(&self) -> Bound {
+ pub fn get_lower_bound(&self) -> Bound {
Bound::new("0.0.0.0-dev".to_string(), false)
}
+}
- fn get_lower_bound(&self) -> Bound {
- Bound::new("0.0.0.0-dev".to_string(), false)
+impl std::fmt::Display for MatchNoneConstraint {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "[]")
}
}
diff --git a/crates/shirabe-semver/src/constraint/multi_constraint.rs b/crates/shirabe-semver/src/constraint/multi_constraint.rs
index 4222095..05cc16e 100644
--- a/crates/shirabe-semver/src/constraint/multi_constraint.rs
+++ b/crates/shirabe-semver/src/constraint/multi_constraint.rs
@@ -1,30 +1,22 @@
//! ref: composer/vendor/composer/semver/src/Constraint/MultiConstraint.php
-use std::cell::RefCell;
-
+use crate::constraint::AnyConstraint;
use crate::constraint::Bound;
-use crate::constraint::ConstraintInterface;
use crate::constraint::MatchAllConstraint;
+#[derive(Debug, Clone)]
pub struct MultiConstraint {
- pub(crate) constraints: Vec<Box<dyn ConstraintInterface>>,
+ pub(crate) constraints: Vec<AnyConstraint>,
pub(crate) pretty_string: Option<String>,
- string: RefCell<Option<String>>,
pub(crate) conjunctive: bool,
- lower_bound: RefCell<Option<Bound>>,
- upper_bound: RefCell<Option<Bound>>,
-}
-
-impl std::fmt::Debug for MultiConstraint {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("MultiConstraint")
- .field("conjunctive", &self.conjunctive)
- .finish()
- }
}
impl MultiConstraint {
- pub fn new(constraints: Vec<Box<dyn ConstraintInterface>>, conjunctive: bool) -> Self {
+ pub fn new(
+ constraints: Vec<AnyConstraint>,
+ conjunctive: bool,
+ pretty_string: Option<String>,
+ ) -> Self {
assert!(
constraints.len() >= 2,
"Must provide at least two constraints for a MultiConstraint. Use \
@@ -34,15 +26,12 @@ impl MultiConstraint {
Self {
constraints,
- pretty_string: None,
- string: RefCell::new(None),
+ pretty_string,
conjunctive,
- lower_bound: RefCell::new(None),
- upper_bound: RefCell::new(None),
}
}
- pub fn get_constraints(&self) -> &[Box<dyn ConstraintInterface>] {
+ pub fn get_constraints(&self) -> &[AnyConstraint] {
&self.constraints
}
@@ -54,11 +43,9 @@ impl MultiConstraint {
!self.conjunctive
}
- fn extract_bounds(&self) {
- if self.lower_bound.borrow().is_some() {
- return;
- }
-
+ /// Composer memoizes the result; this port recomputes on every call. It is not heavy
+ /// calculation so caching is a premature optimization.
+ fn extract_bounds(&self) -> (Bound, Bound) {
let mut current_lower: Option<Bound> = None;
let mut current_upper: Option<Bound> = None;
@@ -93,52 +80,61 @@ impl MultiConstraint {
}
}
- *self.lower_bound.borrow_mut() = current_lower;
- *self.upper_bound.borrow_mut() = current_upper;
+ (
+ current_lower.expect("MultiConstraint always has at least two constraints"),
+ current_upper.expect("MultiConstraint always has at least two constraints"),
+ )
}
pub fn create(
- constraints: Vec<Box<dyn ConstraintInterface>>,
+ constraints: Vec<AnyConstraint>,
conjunctive: bool,
- ) -> anyhow::Result<Box<dyn ConstraintInterface>> {
+ pretty_string: Option<String>,
+ ) -> anyhow::Result<AnyConstraint> {
if constraints.is_empty() {
- return Ok(Box::new(MatchAllConstraint {
- pretty_string: None,
- }));
+ return Ok(MatchAllConstraint::new(pretty_string).into());
}
if constraints.len() == 1 {
- return Ok(constraints.into_iter().next().unwrap());
+ let mut single = constraints.into_iter().next().unwrap();
+ if pretty_string.is_some() {
+ single.set_pretty_string(pretty_string);
+ }
+ return Ok(single);
}
let (constraints, conjunctive) = Self::optimize_constraints(constraints, conjunctive);
if constraints.len() == 1 {
- return Ok(constraints.into_iter().next().unwrap());
+ let mut single = constraints.into_iter().next().unwrap();
+ if pretty_string.is_some() {
+ single.set_pretty_string(pretty_string);
+ }
+ return Ok(single);
}
- Ok(Box::new(MultiConstraint::new(constraints, conjunctive)))
+ Ok(MultiConstraint::new(constraints, conjunctive, pretty_string).into())
}
// Returns the (possibly optimized) constraints and the effective conjunctive flag.
// Always returns the constraints vector (consuming it), whether or not optimization was applied.
// The PHP version returns null for no optimization; here we return the original values unchanged.
fn optimize_constraints(
- constraints: Vec<Box<dyn ConstraintInterface>>,
+ constraints: Vec<AnyConstraint>,
conjunctive: bool,
- ) -> (Vec<Box<dyn ConstraintInterface>>, bool) {
+ ) -> (Vec<AnyConstraint>, bool) {
// Parse the two OR groups and if they are contiguous collapse into one constraint.
// [>= 1 < 2] || [>= 2 < 3] || [>= 3 < 4] => [>= 1 < 4]
if !conjunctive {
let mut iter = constraints.into_iter();
- let mut left: Box<dyn ConstraintInterface> = iter.next().unwrap();
- let mut merged_constraints: Vec<Box<dyn ConstraintInterface>> = Vec::new();
+ let mut left: AnyConstraint = iter.next().unwrap();
+ let mut merged_constraints: Vec<AnyConstraint> = Vec::new();
let mut optimized = false;
for right in iter {
- let merged: Option<Box<dyn ConstraintInterface>> = {
- let maybe_l_mc = left.as_any().downcast_ref::<MultiConstraint>();
- let maybe_r_mc = right.as_any().downcast_ref::<MultiConstraint>();
+ let merged: Option<AnyConstraint> = {
+ let maybe_l_mc = left.as_multi_constraint();
+ let maybe_r_mc = right.as_multi_constraint();
if let (Some(l_mc), Some(r_mc)) = (maybe_l_mc, maybe_r_mc) {
if l_mc.conjunctive
@@ -146,10 +142,10 @@ impl MultiConstraint {
&& l_mc.constraints.len() == 2
&& r_mc.constraints.len() == 2
{
- let left0 = l_mc.constraints[0].__to_string();
- let left1 = l_mc.constraints[1].__to_string();
- let right0 = r_mc.constraints[0].__to_string();
- let right1 = r_mc.constraints[1].__to_string();
+ let left0 = l_mc.constraints[0].to_string();
+ let left1 = l_mc.constraints[1].to_string();
+ let right0 = r_mc.constraints[0].to_string();
+ let right1 = r_mc.constraints[1].to_string();
if left0.starts_with(">=")
&& left1.starts_with('<')
@@ -157,14 +153,17 @@ impl MultiConstraint {
&& right1.starts_with('<')
&& left1.get(2..) == right0.get(3..)
{
- Some(Box::new(MultiConstraint::new(
- vec![
- l_mc.constraints[0].clone_box(),
- r_mc.constraints[1].clone_box(),
- ],
- true,
- ))
- as Box<dyn ConstraintInterface>)
+ Some(
+ MultiConstraint::new(
+ vec![
+ l_mc.constraints[0].clone(),
+ r_mc.constraints[1].clone(),
+ ],
+ true,
+ None,
+ )
+ .into(),
+ )
} else {
None
}
@@ -198,10 +197,8 @@ impl MultiConstraint {
(constraints, conjunctive)
}
-}
-impl ConstraintInterface for MultiConstraint {
- fn compile(&self, other_operator: i64) -> String {
+ pub fn compile(&self, other_operator: i64) -> String {
let mut parts = Vec::new();
for constraint in &self.constraints {
let code = constraint.compile(other_operator);
@@ -233,87 +230,28 @@ impl ConstraintInterface for MultiConstraint {
}
}
- fn matches(&self, provider: &dyn ConstraintInterface) -> bool {
- if !self.conjunctive {
- for constraint in &self.constraints {
- if provider.matches(constraint.as_ref()) {
- return true;
- }
- }
- return false;
- }
-
- if provider.is_disjunctive() {
- return provider.matches(self);
- }
-
- for constraint in &self.constraints {
- if !provider.matches(constraint.as_ref()) {
- return false;
- }
- }
-
- true
- }
-
- fn set_pretty_string(&mut self, pretty_string: Option<String>) {
- self.pretty_string = pretty_string;
- }
-
- fn get_pretty_string(&self) -> String {
+ pub fn get_pretty_string(&self) -> String {
if let Some(ref s) = self.pretty_string
&& !s.is_empty()
{
return s.clone();
}
- self.__to_string()
- }
-
- fn __to_string(&self) -> String {
- if let Some(ref s) = *self.string.borrow() {
- return s.clone();
- }
-
- let parts: Vec<String> = self.constraints.iter().map(|c| c.__to_string()).collect();
- let sep = if self.conjunctive { " " } else { " || " };
- let result = format!("[{}]", parts.join(sep));
-
- *self.string.borrow_mut() = Some(result.clone());
- result
- }
-
- fn get_lower_bound(&self) -> Bound {
- self.extract_bounds();
- self.lower_bound
- .borrow()
- .clone()
- .expect("extractBounds should have populated the lowerBound property")
- }
-
- fn get_upper_bound(&self) -> Bound {
- self.extract_bounds();
- self.upper_bound
- .borrow()
- .clone()
- .expect("extractBounds should have populated the upperBound property")
+ self.to_string()
}
- fn is_disjunctive(&self) -> bool {
- !self.conjunctive
+ pub fn get_lower_bound(&self) -> Bound {
+ self.extract_bounds().0
}
- fn clone_box(&self) -> Box<dyn ConstraintInterface> {
- Box::new(MultiConstraint {
- constraints: self.constraints.iter().map(|c| c.clone_box()).collect(),
- pretty_string: self.pretty_string.clone(),
- string: RefCell::new(self.string.borrow().clone()),
- conjunctive: self.conjunctive,
- lower_bound: RefCell::new(self.lower_bound.borrow().clone()),
- upper_bound: RefCell::new(self.upper_bound.borrow().clone()),
- })
+ pub fn get_upper_bound(&self) -> Bound {
+ self.extract_bounds().1
}
+}
- fn as_any(&self) -> &dyn std::any::Any {
- self
+impl std::fmt::Display for MultiConstraint {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let parts: Vec<String> = self.constraints.iter().map(|c| c.to_string()).collect();
+ let sep = if self.conjunctive { " " } else { " || " };
+ write!(f, "[{}]", parts.join(sep))
}
}
diff --git a/crates/shirabe-semver/src/constraint/constraint.rs b/crates/shirabe-semver/src/constraint/simple_constraint.rs
index 3ac633d..161425a 100644
--- a/crates/shirabe-semver/src/constraint/constraint.rs
+++ b/crates/shirabe-semver/src/constraint/simple_constraint.rs
@@ -1,23 +1,19 @@
//! ref: composer/vendor/composer/semver/src/Constraint/Constraint.php
-use std::sync::Mutex;
-
use anyhow::bail;
use shirabe_php_shim as php;
use crate::constraint::Bound;
-use crate::constraint::ConstraintInterface;
-#[derive(Debug)]
-pub struct Constraint {
+/// Corresponds to PHP's `Constraint`.
+#[derive(Debug, Clone)]
+pub struct SimpleConstraint {
pub(crate) operator: i64,
pub(crate) version: String,
pub(crate) pretty_string: Option<String>,
- pub(crate) lower_bound: Mutex<Option<Bound>>,
- pub(crate) upper_bound: Mutex<Option<Bound>>,
}
-impl Constraint {
+impl SimpleConstraint {
pub const OP_EQ: i64 = 0;
pub const OP_LT: i64 = 1;
pub const OP_LE: i64 = 2;
@@ -60,8 +56,7 @@ impl Constraint {
}
}
- pub fn new(operator: impl Into<String>, version: impl Into<String>) -> Self {
- let operator: String = operator.into();
+ pub fn new(operator: String, version: String, pretty_string: Option<String>) -> Self {
let op_int = Self::trans_op_str(&operator).unwrap_or_else(|| {
// PHP raises InvalidArgumentException; in the Rust port keep that as a panic
// because invalid operators are programmer errors caught during porting.
@@ -74,10 +69,8 @@ impl Constraint {
Self {
operator: op_int,
- version: version.into(),
- pretty_string: None,
- lower_bound: Mutex::new(None),
- upper_bound: Mutex::new(None),
+ version,
+ pretty_string,
}
}
@@ -225,7 +218,7 @@ impl Constraint {
format!("!$b && {}", code_comparison)
}
- pub fn match_specific(&self, provider: &Constraint, compare_branches: bool) -> bool {
+ pub fn match_specific(&self, provider: &SimpleConstraint, compare_branches: bool) -> bool {
let no_equal_op = Self::trans_op_int(self.operator).replace('=', "");
let provider_no_equal_op = Self::trans_op_int(provider.operator).replace('=', "");
@@ -286,18 +279,14 @@ impl Constraint {
false
}
- fn extract_bounds(&self) {
- if self.lower_bound.lock().unwrap().is_some() {
- return;
- }
-
+ /// Composer memoizes the result; this port recomputes on every call. It is not heavy
+ /// calculation so caching is a premature optimization.
+ fn extract_bounds(&self) -> (Bound, Bound) {
if self.version.starts_with("dev-") {
- *self.lower_bound.lock().unwrap() = Some(Bound::zero());
- *self.upper_bound.lock().unwrap() = Some(Bound::positive_infinity());
- return;
+ return (Bound::zero(), Bound::positive_infinity());
}
- let (lower, upper) = match self.operator {
+ match self.operator {
Self::OP_EQ => (
Bound::new(self.version.clone(), true),
Bound::new(self.version.clone(), true),
@@ -314,96 +303,33 @@ impl Constraint {
),
Self::OP_NE => (Bound::zero(), Bound::positive_infinity()),
_ => panic!("unknown operator: {}", self.operator),
- };
-
- *self.lower_bound.lock().unwrap() = Some(lower);
- *self.upper_bound.lock().unwrap() = Some(upper);
- }
-}
-
-impl Clone for Constraint {
- fn clone(&self) -> Self {
- Self {
- operator: self.operator,
- version: self.version.clone(),
- pretty_string: self.pretty_string.clone(),
- lower_bound: Mutex::new(self.lower_bound.lock().unwrap().clone()),
- upper_bound: Mutex::new(self.upper_bound.lock().unwrap().clone()),
}
}
-}
-impl ConstraintInterface for Constraint {
- fn matches(&self, provider: &dyn ConstraintInterface) -> bool {
- if let Some(p) = provider.as_any().downcast_ref::<Constraint>() {
- return self.match_specific(p, false);
- }
- provider.matches(self)
- }
-
- fn compile(&self, other_operator: i64) -> String {
+ pub fn compile(&self, other_operator: i64) -> String {
self.compile_constraint(other_operator)
}
- fn set_pretty_string(&mut self, pretty_string: Option<String>) {
- self.pretty_string = pretty_string;
- }
-
- fn get_pretty_string(&self) -> String {
+ pub fn get_pretty_string(&self) -> String {
if let Some(ref s) = self.pretty_string
&& !s.is_empty()
{
return s.clone();
}
- self.__to_string()
+ self.to_string()
}
- fn __to_string(&self) -> String {
- format!("{} {}", Self::trans_op_int(self.operator), self.version)
+ pub fn get_lower_bound(&self) -> Bound {
+ self.extract_bounds().0
}
- fn get_lower_bound(&self) -> Bound {
- self.extract_bounds();
- self.lower_bound
- .lock()
- .unwrap()
- .clone()
- .expect("extract_bounds should have set lower_bound")
- }
-
- fn get_upper_bound(&self) -> Bound {
- self.extract_bounds();
- self.upper_bound
- .lock()
- .unwrap()
- .clone()
- .expect("extract_bounds should have set upper_bound")
- }
-
- fn clone_box(&self) -> Box<dyn ConstraintInterface> {
- Box::new(self.clone())
- }
-
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn is_constraint(&self) -> bool {
- true
- }
-
- fn get_operator(&self) -> &'static str {
- Self::trans_op_int(self.operator)
- }
-
- fn get_version(&self) -> &str {
- &self.version
+ pub fn get_upper_bound(&self) -> Bound {
+ self.extract_bounds().1
}
}
-impl std::fmt::Display for Constraint {
+impl std::fmt::Display for SimpleConstraint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- use crate::constraint::ConstraintInterface;
- write!(f, "{}", ConstraintInterface::__to_string(self))
+ write!(f, "{} {}", Self::trans_op_int(self.operator), self.version)
}
}
diff --git a/crates/shirabe-semver/src/interval.rs b/crates/shirabe-semver/src/interval.rs
index b1f3010..7f27514 100644
--- a/crates/shirabe-semver/src/interval.rs
+++ b/crates/shirabe-semver/src/interval.rs
@@ -1,8 +1,6 @@
//! ref: composer/vendor/composer/semver/src/Interval.php
-use std::sync::OnceLock;
-
-use crate::constraint::Constraint;
+use crate::constraint::SimpleConstraint;
#[derive(Debug, Clone)]
pub struct DevConstraintSet {
@@ -12,32 +10,29 @@ pub struct DevConstraintSet {
#[derive(Debug, Clone)]
pub struct Interval {
- start: Constraint,
- end: Constraint,
+ start: SimpleConstraint,
+ end: SimpleConstraint,
}
impl Interval {
- pub fn new(start: Constraint, end: Constraint) -> Self {
+ pub fn new(start: SimpleConstraint, end: SimpleConstraint) -> Self {
Self { start, end }
}
- pub fn get_start(&self) -> &Constraint {
+ pub fn get_start(&self) -> &SimpleConstraint {
&self.start
}
- pub fn get_end(&self) -> &Constraint {
+ pub fn get_end(&self) -> &SimpleConstraint {
&self.end
}
- pub fn from_zero() -> &'static Constraint {
- static ZERO: OnceLock<Constraint> = OnceLock::new();
- ZERO.get_or_init(|| Constraint::new(">=".to_string(), "0.0.0.0-dev".to_string()))
+ pub fn from_zero() -> SimpleConstraint {
+ SimpleConstraint::new(">=".to_string(), "0.0.0.0-dev".to_string(), None)
}
- pub fn until_positive_infinity() -> &'static Constraint {
- static POSITIVE_INFINITY: OnceLock<Constraint> = OnceLock::new();
- POSITIVE_INFINITY
- .get_or_init(|| Constraint::new("<".to_string(), format!("{}.0.0.0", i64::MAX)))
+ pub fn until_positive_infinity() -> SimpleConstraint {
+ SimpleConstraint::new("<".to_string(), format!("{}.0.0.0", i64::MAX), None)
}
pub fn any() -> Self {
diff --git a/crates/shirabe-semver/src/intervals.rs b/crates/shirabe-semver/src/intervals.rs
index 72231b6..68b23bf 100644
--- a/crates/shirabe-semver/src/intervals.rs
+++ b/crates/shirabe-semver/src/intervals.rs
@@ -3,11 +3,11 @@
use std::collections::HashMap;
use std::sync::{Mutex, OnceLock};
-use crate::constraint::Constraint;
-use crate::constraint::ConstraintInterface;
+use crate::constraint::AnyConstraint;
use crate::constraint::MatchAllConstraint;
use crate::constraint::MatchNoneConstraint;
use crate::constraint::MultiConstraint;
+use crate::constraint::SimpleConstraint;
use crate::interval::{DevConstraintSet, Interval};
use shirabe_php_shim as php;
@@ -42,31 +42,19 @@ impl Intervals {
}
pub fn is_subset_of(
- candidate: &dyn ConstraintInterface,
- constraint: &dyn ConstraintInterface,
+ candidate: &AnyConstraint,
+ constraint: &AnyConstraint,
) -> anyhow::Result<bool> {
- if constraint
- .as_any()
- .downcast_ref::<MatchAllConstraint>()
- .is_some()
- {
+ if constraint.is_match_all() {
return Ok(true);
}
- if candidate
- .as_any()
- .downcast_ref::<MatchNoneConstraint>()
- .is_some()
- || constraint
- .as_any()
- .downcast_ref::<MatchNoneConstraint>()
- .is_some()
- {
+ if candidate.is_match_none() || constraint.is_match_none() {
return Ok(false);
}
- // Phase B: ConstraintInterface needs clone_box() to create owned copies from references.
- let multi = MultiConstraint::new(vec![candidate.clone_box(), constraint.clone_box()], true);
+ let multi =
+ MultiConstraint::new(vec![candidate.clone(), constraint.clone()], true, None).into();
let intersection_intervals = Self::get(&multi)?;
let candidate_intervals = Self::get(candidate)?;
@@ -79,14 +67,14 @@ impl Intervals {
return Ok(false);
}
- if candidate_intervals.numeric[index].get_start().__to_string()
- != interval.get_start().__to_string()
+ if candidate_intervals.numeric[index].get_start().to_string()
+ != interval.get_start().to_string()
{
return Ok(false);
}
- if candidate_intervals.numeric[index].get_end().__to_string()
- != interval.get_end().__to_string()
+ if candidate_intervals.numeric[index].get_end().to_string()
+ != interval.get_end().to_string()
{
return Ok(false);
}
@@ -107,24 +95,16 @@ impl Intervals {
Ok(true)
}
- pub fn have_intersections(
- a: &dyn ConstraintInterface,
- b: &dyn ConstraintInterface,
- ) -> anyhow::Result<bool> {
- if a.as_any().downcast_ref::<MatchAllConstraint>().is_some()
- || b.as_any().downcast_ref::<MatchAllConstraint>().is_some()
- {
+ pub fn have_intersections(a: &AnyConstraint, b: &AnyConstraint) -> anyhow::Result<bool> {
+ if a.is_match_all() || b.is_match_all() {
return Ok(true);
}
- if a.as_any().downcast_ref::<MatchNoneConstraint>().is_some()
- || b.as_any().downcast_ref::<MatchNoneConstraint>().is_some()
- {
+ if a.is_match_none() || b.is_match_none() {
return Ok(false);
}
- // Phase B: ConstraintInterface needs clone_box().
- let multi = MultiConstraint::new(vec![a.clone_box(), b.clone_box()], true);
+ let multi = MultiConstraint::new(vec![a.clone(), b.clone()], true, None).into();
let intersection_intervals = Self::generate_intervals(&multi, true)?;
Ok(!intersection_intervals.numeric.is_empty()
@@ -132,30 +112,24 @@ impl Intervals {
|| !intersection_intervals.branches.names.is_empty())
}
- pub fn compact_constraint(
- constraint: &dyn ConstraintInterface,
- ) -> anyhow::Result<Box<dyn ConstraintInterface>> {
- if constraint
- .as_any()
- .downcast_ref::<MultiConstraint>()
- .is_none()
- {
- return Ok(constraint.clone_box());
+ pub fn compact_constraint(constraint: &AnyConstraint) -> anyhow::Result<AnyConstraint> {
+ if constraint.as_multi_constraint().is_none() {
+ return Ok(constraint.clone());
}
let intervals = Self::generate_intervals(constraint, false)?;
- let mut constraints: Vec<Box<dyn ConstraintInterface>> = Vec::new();
+ let mut constraints: Vec<AnyConstraint> = Vec::new();
let mut has_numeric_match_all = false;
if intervals.numeric.len() == 1
- && intervals.numeric[0].get_start().__to_string() == Interval::from_zero().__to_string()
- && intervals.numeric[0].get_end().__to_string()
- == Interval::until_positive_infinity().__to_string()
+ && intervals.numeric[0].get_start().to_string() == Interval::from_zero().to_string()
+ && intervals.numeric[0].get_end().to_string()
+ == Interval::until_positive_infinity().to_string()
{
- constraints.push(Box::new(intervals.numeric[0].get_start().clone()));
+ constraints.push(intervals.numeric[0].get_start().clone().into());
has_numeric_match_all = true;
} else {
- let mut un_equal_constraints: Vec<Box<dyn ConstraintInterface>> = Vec::new();
+ let mut un_equal_constraints: Vec<AnyConstraint> = Vec::new();
let count = intervals.numeric.len();
let mut i = 0;
while i < count {
@@ -176,15 +150,18 @@ impl Intervals {
// unEqualConstraints currently contains [>=M, !=N] already and we only
// want to add !=P right now
if un_equal_constraints.is_empty()
- && interval.get_start().__to_string()
- != Interval::from_zero().__to_string()
+ && interval.get_start().to_string() != Interval::from_zero().to_string()
{
- un_equal_constraints.push(Box::new(interval.get_start().clone()));
+ un_equal_constraints.push(interval.get_start().clone().into());
}
- un_equal_constraints.push(Box::new(Constraint::new(
- "!=".to_string(),
- interval.get_end().get_version().to_string(),
- )));
+ un_equal_constraints.push(
+ SimpleConstraint::new(
+ "!=".to_string(),
+ interval.get_end().get_version().to_string(),
+ None,
+ )
+ .into(),
+ );
i += 1;
continue;
}
@@ -192,16 +169,16 @@ impl Intervals {
if !un_equal_constraints.is_empty() {
// this is where the end of the following interval of a != constraint is added
- if interval.get_end().__to_string()
- != Interval::until_positive_infinity().__to_string()
+ if interval.get_end().to_string()
+ != Interval::until_positive_infinity().to_string()
{
- un_equal_constraints.push(Box::new(interval.get_end().clone()));
+ un_equal_constraints.push(interval.get_end().clone().into());
}
// count is 1 if entire constraint is just one != expression
if un_equal_constraints.len() > 1 {
constraints
- .push(Box::new(MultiConstraint::new(un_equal_constraints, true)));
+ .push(MultiConstraint::new(un_equal_constraints, true, None).into());
} else {
constraints.push(un_equal_constraints.into_iter().next().unwrap());
}
@@ -216,55 +193,59 @@ impl Intervals {
&& interval.get_start().get_operator() == ">="
&& interval.get_end().get_operator() == "<="
{
- constraints.push(Box::new(Constraint::new(
- "==".to_string(),
- interval.get_start().get_version().to_string(),
- )));
+ constraints.push(
+ SimpleConstraint::new(
+ "==".to_string(),
+ interval.get_start().get_version().to_string(),
+ None,
+ )
+ .into(),
+ );
i += 1;
continue;
}
- if interval.get_start().__to_string() == Interval::from_zero().__to_string() {
- constraints.push(Box::new(interval.get_end().clone()));
- } else if interval.get_end().__to_string()
- == Interval::until_positive_infinity().__to_string()
+ if interval.get_start().to_string() == Interval::from_zero().to_string() {
+ constraints.push(interval.get_end().clone().into());
+ } else if interval.get_end().to_string()
+ == Interval::until_positive_infinity().to_string()
{
- constraints.push(Box::new(interval.get_start().clone()));
+ constraints.push(interval.get_start().clone().into());
} else {
- constraints.push(Box::new(MultiConstraint::new(
- vec![
- Box::new(interval.get_start().clone()),
- Box::new(interval.get_end().clone()),
- ],
- true,
- )));
+ constraints.push(
+ MultiConstraint::new(
+ vec![
+ AnyConstraint::Simple(interval.get_start().clone()),
+ AnyConstraint::Simple(interval.get_end().clone()),
+ ],
+ true,
+ None,
+ )
+ .into(),
+ );
}
i += 1;
}
}
- let mut dev_constraints: Vec<Box<dyn ConstraintInterface>> = Vec::new();
+ let mut dev_constraints: Vec<AnyConstraint> = Vec::new();
if intervals.branches.names.is_empty() {
if intervals.branches.exclude && has_numeric_match_all {
- return Ok(Box::new(MatchAllConstraint {
- pretty_string: None,
- }));
+ return Ok(MatchAllConstraint::new(None).into());
// otherwise constraint should contain a != operator and already cover this
}
} else {
for branch_name in &intervals.branches.names {
if intervals.branches.exclude {
- dev_constraints.push(Box::new(Constraint::new(
- "!=".to_string(),
- branch_name.clone(),
- )));
+ dev_constraints.push(
+ SimpleConstraint::new("!=".to_string(), branch_name.clone(), None).into(),
+ );
} else {
- dev_constraints.push(Box::new(Constraint::new(
- "==".to_string(),
- branch_name.clone(),
- )));
+ dev_constraints.push(
+ SimpleConstraint::new("==".to_string(), branch_name.clone(), None).into(),
+ );
}
}
@@ -272,26 +253,25 @@ impl Intervals {
// > 2.0 != dev-foo must return a conjunctive constraint
if intervals.branches.exclude {
if constraints.len() > 1 {
- let merged: Vec<Box<dyn ConstraintInterface>> =
- std::iter::once(Box::new(MultiConstraint::new(constraints, false))
- as Box<dyn ConstraintInterface>)
- .chain(dev_constraints)
- .collect();
- return Ok(Box::new(MultiConstraint::new(merged, true)));
+ let merged: Vec<AnyConstraint> =
+ std::iter::once(MultiConstraint::new(constraints, false, None).into())
+ .chain(dev_constraints)
+ .collect();
+ return Ok(MultiConstraint::new(merged, true, None).into());
}
if constraints.len() == 1
- && constraints[0].__to_string() == Interval::from_zero().__to_string()
+ && constraints[0].to_string() == Interval::from_zero().to_string()
{
if dev_constraints.len() > 1 {
- return Ok(Box::new(MultiConstraint::new(dev_constraints, true)));
+ return Ok(MultiConstraint::new(dev_constraints, true, None).into());
}
return Ok(dev_constraints.into_iter().next().unwrap());
}
- let merged: Vec<Box<dyn ConstraintInterface>> =
+ let merged: Vec<AnyConstraint> =
constraints.into_iter().chain(dev_constraints).collect();
- return Ok(Box::new(MultiConstraint::new(merged, true)));
+ return Ok(MultiConstraint::new(merged, true, None).into());
}
// otherwise devConstraints contains a list of == operators for branches which are
@@ -300,20 +280,18 @@ impl Intervals {
}
if constraints.len() > 1 {
- return Ok(Box::new(MultiConstraint::new(constraints, false)));
+ return Ok(MultiConstraint::new(constraints, false, None).into());
}
if constraints.len() == 1 {
return Ok(constraints.into_iter().next().unwrap());
}
- Ok(Box::new(MatchNoneConstraint {
- pretty_string: None,
- }))
+ Ok(MatchNoneConstraint::new(None).into())
}
- pub fn get(constraint: &dyn ConstraintInterface) -> anyhow::Result<IntervalCollection> {
- let key = constraint.__to_string();
+ pub fn get(constraint: &AnyConstraint) -> anyhow::Result<IntervalCollection> {
+ let key = constraint.to_string();
{
let cache = intervals_cache().lock().unwrap();
@@ -333,14 +311,10 @@ impl Intervals {
}
fn generate_intervals(
- constraint: &dyn ConstraintInterface,
+ constraint: &AnyConstraint,
stop_on_first_valid_interval: bool,
) -> anyhow::Result<IntervalCollection> {
- if constraint
- .as_any()
- .downcast_ref::<MatchAllConstraint>()
- .is_some()
- {
+ if constraint.is_match_all() {
return Ok(IntervalCollection {
numeric: vec![Interval::new(
Interval::from_zero().clone(),
@@ -350,37 +324,30 @@ impl Intervals {
});
}
- if constraint
- .as_any()
- .downcast_ref::<MatchNoneConstraint>()
- .is_some()
- {
+ if constraint.is_match_none() {
return Ok(IntervalCollection {
numeric: vec![],
branches: Interval::no_dev(),
});
}
- if let Some(c) = constraint.as_any().downcast_ref::<Constraint>() {
+ if let Some(c) = constraint.as_constraint() {
return Self::generate_single_constraint_intervals(c);
}
- let multi = constraint
- .as_any()
- .downcast_ref::<MultiConstraint>()
- .ok_or_else(|| {
- anyhow::anyhow!(
- "The constraint passed in should be an MatchAllConstraint, Constraint or \
+ let multi = constraint.as_multi_constraint().ok_or_else(|| {
+ anyhow::anyhow!(
+ "The constraint passed in should be an MatchAllConstraint, Constraint or \
MultiConstraint instance, got an unknown type."
- )
- })?;
+ )
+ })?;
let sub_constraints = multi.get_constraints();
let mut numeric_groups: Vec<Vec<Interval>> = Vec::new();
let mut constraint_branches: Vec<DevConstraintSet> = Vec::new();
for c in sub_constraints {
- let res = Self::get(c.as_ref())?;
+ let res = Self::get(c)?;
numeric_groups.push(res.numeric);
constraint_branches.push(res.branches);
}
@@ -494,7 +461,7 @@ impl Intervals {
} else {
1
};
- let mut start: Option<Constraint> = None;
+ let mut start: Option<SimpleConstraint> = None;
for (version, operator, is_start) in &borders {
if *is_start {
@@ -504,7 +471,11 @@ impl Intervals {
}
if start.is_none() && active_intervals >= activation_threshold {
- start = Some(Constraint::new(operator.clone(), version.clone()));
+ start = Some(SimpleConstraint::new(
+ operator.clone(),
+ version.clone(),
+ None,
+ ));
} else if start.is_some() && active_intervals < activation_threshold {
let start_c = start.take().unwrap();
// filter out invalid intervals like > x - <= x, or >= x - < x
@@ -516,7 +487,7 @@ impl Intervals {
} else {
intervals.push(Interval::new(
start_c,
- Constraint::new(operator.clone(), version.clone()),
+ SimpleConstraint::new(operator.clone(), version.clone(), None),
));
if stop_on_first_valid_interval {
@@ -533,7 +504,7 @@ impl Intervals {
}
fn generate_single_constraint_intervals(
- constraint: &Constraint,
+ constraint: &SimpleConstraint,
) -> anyhow::Result<IntervalCollection> {
let op = constraint.get_operator();
@@ -589,10 +560,18 @@ impl Intervals {
numeric: vec![
Interval::new(
Interval::from_zero().clone(),
- Constraint::new("<".to_string(), constraint.get_version().to_string()),
+ SimpleConstraint::new(
+ "<".to_string(),
+ constraint.get_version().to_string(),
+ None,
+ ),
),
Interval::new(
- Constraint::new(">".to_string(), constraint.get_version().to_string()),
+ SimpleConstraint::new(
+ ">".to_string(),
+ constraint.get_version().to_string(),
+ None,
+ ),
Interval::until_positive_infinity().clone(),
),
],
@@ -603,8 +582,8 @@ impl Intervals {
// convert ==x to an interval of >=x - <=x
Ok(IntervalCollection {
numeric: vec![Interval::new(
- Constraint::new(">=".to_string(), constraint.get_version().to_string()),
- Constraint::new("<=".to_string(), constraint.get_version().to_string()),
+ SimpleConstraint::new(">=".to_string(), constraint.get_version().to_string(), None),
+ SimpleConstraint::new("<=".to_string(), constraint.get_version().to_string(), None),
)],
branches: Interval::no_dev(),
})
diff --git a/crates/shirabe-semver/src/semver.rs b/crates/shirabe-semver/src/semver.rs
index 62f50b6..2314069 100644
--- a/crates/shirabe-semver/src/semver.rs
+++ b/crates/shirabe-semver/src/semver.rs
@@ -3,7 +3,8 @@
use std::sync::OnceLock;
use crate::comparator::Comparator;
-use crate::constraint::Constraint;
+use crate::constraint::AnyConstraint;
+use crate::constraint::SimpleConstraint;
use crate::version_parser::VersionParser;
pub struct Semver;
@@ -19,7 +20,12 @@ impl Semver {
pub fn satisfies(version: String, constraints: String) -> anyhow::Result<bool> {
let version_parser = Self::version_parser();
- let provider = Constraint::new("==".to_string(), version_parser.normalize(&version, None)?);
+ let provider = SimpleConstraint::new(
+ "==".to_string(),
+ version_parser.normalize(&version, None)?,
+ None,
+ )
+ .into();
let parsed_constraints = version_parser.parse_constraints(&constraints)?;
Ok(parsed_constraints.matches(&provider))
}
diff --git a/crates/shirabe-semver/src/version_parser.rs b/crates/shirabe-semver/src/version_parser.rs
index ba2b59d..bbd359e 100644
--- a/crates/shirabe-semver/src/version_parser.rs
+++ b/crates/shirabe-semver/src/version_parser.rs
@@ -1,9 +1,9 @@
//! ref: composer/vendor/composer/semver/src/VersionParser.php
-use crate::constraint::Constraint;
-use crate::constraint::ConstraintInterface;
+use crate::constraint::AnyConstraint;
use crate::constraint::MatchAllConstraint;
use crate::constraint::MultiConstraint;
+use crate::constraint::SimpleConstraint;
use shirabe_php_shim as php;
// Regex to match pre-release data (sort of).
@@ -294,16 +294,13 @@ impl VersionParser {
name.to_string()
}
- pub fn parse_constraints(
- &self,
- constraints: &str,
- ) -> anyhow::Result<Box<dyn ConstraintInterface>> {
+ pub fn parse_constraints(&self, constraints: &str) -> anyhow::Result<AnyConstraint> {
let pretty_constraint = constraints.to_string();
let or_constraints = php::preg_split("{\\s*\\|\\|?\\s*}", &php::trim(constraints, None))
.ok_or_else(|| anyhow::anyhow!("Failed to preg_split string: {}", constraints))?;
- let mut or_groups: Vec<Box<dyn ConstraintInterface>> = Vec::new();
+ let mut or_groups: Vec<AnyConstraint> = Vec::new();
for or_constraint in &or_constraints {
let and_constraints = php::preg_split(
@@ -312,9 +309,8 @@ impl VersionParser {
)
.ok_or_else(|| anyhow::anyhow!("Failed to preg_split string: {}", or_constraint))?;
- let constraint_objects: Vec<Box<dyn ConstraintInterface>> = if and_constraints.len() > 1
- {
- let mut objs: Vec<Box<dyn ConstraintInterface>> = Vec::new();
+ let constraint_objects: Vec<AnyConstraint> = if and_constraints.len() > 1 {
+ let mut objs: Vec<AnyConstraint> = Vec::new();
for and_constraint in &and_constraints {
for parsed in self.parse_constraint(and_constraint)? {
objs.push(parsed);
@@ -325,26 +321,21 @@ impl VersionParser {
self.parse_constraint(&and_constraints[0])?
};
- let constraint: Box<dyn ConstraintInterface> = if constraint_objects.len() == 1 {
+ let constraint: AnyConstraint = if constraint_objects.len() == 1 {
constraint_objects.into_iter().next().unwrap()
} else {
- Box::new(MultiConstraint::new(constraint_objects, true))
+ MultiConstraint::new(constraint_objects, true, None).into()
};
or_groups.push(constraint);
}
- let mut parsed_constraint = MultiConstraint::create(or_groups, false)?;
-
- parsed_constraint.set_pretty_string(Some(pretty_constraint));
-
- Ok(parsed_constraint)
+ // PHP sets the pretty string on the create() result via setPrettyString();
+ // the port threads it through create() instead (no setter).
+ MultiConstraint::create(or_groups, false, Some(pretty_constraint))
}
- fn parse_constraint(
- &self,
- constraint: &str,
- ) -> anyhow::Result<Vec<Box<dyn ConstraintInterface>>> {
+ fn parse_constraint(&self, constraint: &str) -> anyhow::Result<Vec<AnyConstraint>> {
let mut constraint = constraint.to_string();
// strip off aliasing
@@ -399,15 +390,14 @@ impl VersionParser {
.unwrap_or("")
.is_empty();
if m1_nonempty || m2_nonempty {
- return Ok(vec![Box::new(Constraint::new(
+ return Ok(vec![AnyConstraint::Simple(SimpleConstraint::new(
">=".to_string(),
"0.0.0.0-dev".to_string(),
+ None,
))]);
}
- return Ok(vec![Box::new(MatchAllConstraint {
- pretty_string: None,
- })]);
+ return Ok(vec![AnyConstraint::MatchAll(MatchAllConstraint::new(None))]);
}
let version_regex = format!(
@@ -461,7 +451,7 @@ impl VersionParser {
let low_version =
self.normalize(&format!("{}{}", &constraint[1..], stability_suffix), None)?;
- let lower_bound = Constraint::new(">=".to_string(), low_version);
+ let lower_bound = SimpleConstraint::new(">=".to_string(), low_version, None);
// For upper bound, we increment the position of one more significance,
// but highPosition = 0 would be illegal
@@ -471,9 +461,12 @@ impl VersionParser {
self.manipulate_version_string(&matches, high_position, 1, "0")
.unwrap_or_default()
);
- let upper_bound = Constraint::new("<".to_string(), high_version);
+ let upper_bound = SimpleConstraint::new("<".to_string(), high_version, None);
- return Ok(vec![Box::new(lower_bound), Box::new(upper_bound)]);
+ return Ok(vec![
+ AnyConstraint::Simple(lower_bound),
+ AnyConstraint::Simple(upper_bound),
+ ]);
}
// Caret Range
@@ -508,7 +501,7 @@ impl VersionParser {
let low_version =
self.normalize(&format!("{}{}", &constraint[1..], stability_suffix), None)?;
- let lower_bound = Constraint::new(">=".to_string(), low_version);
+ let lower_bound = SimpleConstraint::new(">=".to_string(), low_version, None);
// For upper bound, we increment the position of one more significance,
// but highPosition = 0 would be illegal
@@ -517,9 +510,12 @@ impl VersionParser {
self.manipulate_version_string(&matches, position, 1, "0")
.unwrap_or_default()
);
- let upper_bound = Constraint::new("<".to_string(), high_version);
+ let upper_bound = SimpleConstraint::new("<".to_string(), high_version, None);
- return Ok(vec![Box::new(lower_bound), Box::new(upper_bound)]);
+ return Ok(vec![
+ AnyConstraint::Simple(lower_bound),
+ AnyConstraint::Simple(upper_bound),
+ ]);
}
// X Range
@@ -554,15 +550,16 @@ impl VersionParser {
);
if low_version == "0.0.0.0-dev" {
- return Ok(vec![Box::new(Constraint::new(
+ return Ok(vec![AnyConstraint::Simple(SimpleConstraint::new(
"<".to_string(),
high_version,
+ None,
))]);
}
return Ok(vec![
- Box::new(Constraint::new(">=".to_string(), low_version)),
- Box::new(Constraint::new("<".to_string(), high_version)),
+ AnyConstraint::Simple(SimpleConstraint::new(">=".to_string(), low_version, None)),
+ AnyConstraint::Simple(SimpleConstraint::new("<".to_string(), high_version, None)),
]);
}
@@ -593,9 +590,10 @@ impl VersionParser {
let from_str = matches[1].clone().unwrap_or_default(); // matches['from']
let low_version = self.normalize(&from_str, None)?;
- let lower_bound = Constraint::new(
+ let lower_bound = SimpleConstraint::new(
">=".to_string(),
format!("{}{}", low_version, low_stability_suffix),
+ None,
);
// PHP's empty() on "0" returns true, but here we only check for truly empty/missing
@@ -603,14 +601,14 @@ impl VersionParser {
// matches[12]=to minor, matches[13]=to patch, matches[15]=to stability,
// matches[17]=to dev, matches[18]=to wildcard-dev
- let upper_bound: Constraint = if (!empty(&matches[12]) && !empty(&matches[13]))
+ let upper_bound: SimpleConstraint = if (!empty(&matches[12]) && !empty(&matches[13]))
|| !matches[15].as_deref().unwrap_or("").is_empty()
|| !matches[17].as_deref().unwrap_or("").is_empty()
|| !matches[18].as_deref().unwrap_or("").is_empty()
{
let to_str = matches[10].clone().unwrap_or_default(); // matches['to']
let hv = self.normalize(&to_str, None)?;
- Constraint::new("<=".to_string(), hv)
+ SimpleConstraint::new("<=".to_string(), hv, None)
} else {
// matches[11]=to major, matches[12]=to minor, matches[13]=to patch,
// matches[14]=to fourth
@@ -632,10 +630,13 @@ impl VersionParser {
self.manipulate_version_string(&high_match, position, 1, "0")
.unwrap_or_default()
);
- Constraint::new("<".to_string(), hv)
+ SimpleConstraint::new("<".to_string(), hv, None)
};
- return Ok(vec![Box::new(lower_bound), Box::new(upper_bound)]);
+ return Ok(vec![
+ AnyConstraint::Simple(lower_bound),
+ AnyConstraint::Simple(upper_bound),
+ ]);
}
// Basic Comparators
@@ -691,7 +692,9 @@ impl VersionParser {
} else {
op_str
};
- return Ok(vec![Box::new(Constraint::new(final_op, version))]);
+ return Ok(vec![AnyConstraint::Simple(SimpleConstraint::new(
+ final_op, version, None,
+ ))]);
}
}
diff --git a/crates/shirabe/src/advisory/ignored_security_advisory.rs b/crates/shirabe/src/advisory/ignored_security_advisory.rs
index 1cd5f75..140c00b 100644
--- a/crates/shirabe/src/advisory/ignored_security_advisory.rs
+++ b/crates/shirabe/src/advisory/ignored_security_advisory.rs
@@ -4,7 +4,7 @@ use crate::advisory::SecurityAdvisory;
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
#[derive(Debug, serde::Serialize)]
#[serde(rename_all = "camelCase")]
@@ -19,7 +19,7 @@ impl IgnoredSecurityAdvisory {
pub fn new(
package_name: String,
advisory_id: String,
- affected_versions: Box<dyn ConstraintInterface>,
+ affected_versions: AnyConstraint,
title: String,
sources: Vec<IndexMap<String, String>>,
reported_at: DateTime<Utc>,
diff --git a/crates/shirabe/src/advisory/partial_security_advisory.rs b/crates/shirabe/src/advisory/partial_security_advisory.rs
index 6953ef3..fe3c99e 100644
--- a/crates/shirabe/src/advisory/partial_security_advisory.rs
+++ b/crates/shirabe/src/advisory/partial_security_advisory.rs
@@ -7,12 +7,12 @@ use chrono::{DateTime, TimeZone, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
use shirabe_php_shim::{PhpMixed, UnexpectedValueException};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use shirabe_semver::version_parser::VersionParser;
fn serialize_constraint<S: serde::Serializer>(
- c: &Box<dyn ConstraintInterface>,
+ c: &AnyConstraint,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&c.get_pretty_string())
@@ -24,7 +24,7 @@ pub struct PartialSecurityAdvisory {
pub advisory_id: String,
pub package_name: String,
#[serde(serialize_with = "serialize_constraint")]
- pub affected_versions: Box<dyn ConstraintInterface>,
+ pub affected_versions: AnyConstraint,
}
impl PartialSecurityAdvisory {
@@ -35,21 +35,22 @@ impl PartialSecurityAdvisory {
) -> Result<PartialOrSecurityAdvisory> {
let affected_versions_str = data["affectedVersions"].as_string().unwrap_or("");
- let constraint: Box<dyn ConstraintInterface> =
- match parser.parse_constraints(affected_versions_str) {
- Ok(c) => c,
- Err(_) => {
- let affected_version =
- Preg::replace(r"(^[>=<^~]*[\d.]+).*", "$1", affected_versions_str);
- match parser.parse_constraints(affected_version.as_deref().unwrap_or("")) {
- Ok(c) => c,
- Err(_) => Box::new(Constraint::new(
- "==".to_string(),
- "0.0.0-invalid-version".to_string(),
- )),
- }
+ let constraint: AnyConstraint = match parser.parse_constraints(affected_versions_str) {
+ Ok(c) => c,
+ Err(_) => {
+ let affected_version =
+ Preg::replace(r"(^[>=<^~]*[\d.]+).*", "$1", affected_versions_str);
+ match parser.parse_constraints(affected_version.as_deref().unwrap_or("")) {
+ Ok(c) => c,
+ Err(_) => SimpleConstraint::new(
+ "==".to_string(),
+ "0.0.0-invalid-version".to_string(),
+ None,
+ )
+ .into(),
}
- };
+ }
+ };
let has_full_data = data.contains_key("title")
&& data.contains_key("sources")
@@ -93,7 +94,7 @@ impl PartialSecurityAdvisory {
pub fn new(
package_name: String,
advisory_id: String,
- affected_versions: Box<dyn ConstraintInterface>,
+ affected_versions: AnyConstraint,
) -> Self {
Self {
advisory_id,
diff --git a/crates/shirabe/src/advisory/security_advisory.rs b/crates/shirabe/src/advisory/security_advisory.rs
index 9787d37..edb161c 100644
--- a/crates/shirabe/src/advisory/security_advisory.rs
+++ b/crates/shirabe/src/advisory/security_advisory.rs
@@ -2,7 +2,7 @@
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use crate::advisory::IgnoredSecurityAdvisory;
use crate::advisory::PartialSecurityAdvisory;
@@ -24,7 +24,7 @@ impl SecurityAdvisory {
pub fn new(
package_name: String,
advisory_id: String,
- affected_versions: Box<dyn ConstraintInterface>,
+ affected_versions: AnyConstraint,
title: String,
sources: Vec<IndexMap<String, String>>,
reported_at: DateTime<Utc>,
@@ -48,15 +48,15 @@ impl SecurityAdvisory {
&self.inner.advisory_id
}
- pub fn affected_versions(&self) -> &dyn ConstraintInterface {
- &*self.inner.affected_versions
+ pub fn affected_versions(&self) -> &AnyConstraint {
+ &self.inner.affected_versions
}
pub fn to_ignored_advisory(&self, ignore_reason: Option<String>) -> IgnoredSecurityAdvisory {
IgnoredSecurityAdvisory::new(
self.inner.package_name.clone(),
self.inner.advisory_id.clone(),
- self.inner.affected_versions.clone_box(),
+ self.inner.affected_versions.clone(),
self.title.clone(),
self.sources.clone(),
self.reported_at,
diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs
index 7b7980a..5c9f008 100644
--- a/crates/shirabe/src/autoload/autoload_generator.rs
+++ b/crates/shirabe/src/autoload/autoload_generator.rs
@@ -14,8 +14,8 @@ use shirabe_php_shim::{
sprintf, str_contains, str_replace, str_starts_with, strlen, strpos, strtr, substr,
substr_count, trigger_error, trim, unlink, var_export,
};
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::Bound;
-use shirabe_semver::constraint::ConstraintInterface;
use crate::autoload::ClassLoader;
use crate::config::Config;
@@ -1092,7 +1092,7 @@ impl AutoloadGenerator {
let mut required_extensions: IndexMap<String, String> = IndexMap::new();
let mut extension_providers: IndexMap<
String,
- Vec<Box<dyn shirabe_semver::constraint::ConstraintInterface>>,
+ Vec<shirabe_semver::constraint::AnyConstraint>,
> = IndexMap::new();
for item in package_map {
@@ -1110,7 +1110,7 @@ impl AutoloadGenerator {
extension_providers
.entry(ext)
.or_insert_with(Vec::new)
- .push(link.get_constraint().clone_box());
+ .push(link.get_constraint().clone());
}
}
}
diff --git a/crates/shirabe/src/command/archive_command.rs b/crates/shirabe/src/command/archive_command.rs
index c88b47b..0813df6 100644
--- a/crates/shirabe/src/command/archive_command.rs
+++ b/crates/shirabe/src/command/archive_command.rs
@@ -305,11 +305,11 @@ impl ArchiveCommand {
);
repo_set.add_repository(Box::new(repo))?;
let parser = VersionParser::new();
- let constraint: Option<Box<dyn shirabe_semver::constraint::ConstraintInterface>> =
- match version.as_deref() {
- Some(v) => Some(parser.parse_constraints(v)?.clone_box()),
- None => None,
- };
+ let constraint: Option<shirabe_semver::constraint::AnyConstraint> = match version.as_deref()
+ {
+ Some(v) => Some(parser.parse_constraints(v)?.clone()),
+ None => None,
+ };
let packages = repo_set.find_packages(&package_name.to_lowercase(), constraint, 0);
let package = if packages.len() > 1 {
diff --git a/crates/shirabe/src/command/base_dependency_command.rs b/crates/shirabe/src/command/base_dependency_command.rs
index 498c589..f1ff863 100644
--- a/crates/shirabe/src/command/base_dependency_command.rs
+++ b/crates/shirabe/src/command/base_dependency_command.rs
@@ -6,8 +6,8 @@ use shirabe_external_packages::symfony::component::console::input::InputInterfac
use shirabe_external_packages::symfony::component::console::output::OutputInterface;
use shirabe_external_packages::symfony::console::formatter::OutputFormatter;
use shirabe_php_shim::{InvalidArgumentException, PhpMixed, UnexpectedValueException};
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::Bound;
-use shirabe_semver::constraint::ConstraintInterface;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
use crate::package::CompletePackageInterface;
@@ -225,13 +225,9 @@ pub trait BaseDependencyCommand: BaseCommand {
}
let has_constraint = text_constraint != "*";
- let constraint: Option<Box<dyn ConstraintInterface>> = if has_constraint {
+ let constraint: Option<AnyConstraint> = if has_constraint {
let version_parser = VersionParser::new();
- Some(
- version_parser
- .parse_constraints(&text_constraint)?
- .clone_box(),
- )
+ Some(version_parser.parse_constraints(&text_constraint)?.clone())
} else {
None
};
diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs
index 83770be..74ecfc3 100644
--- a/crates/shirabe/src/command/check_platform_reqs_command.rs
+++ b/crates/shirabe/src/command/check_platform_reqs_command.rs
@@ -5,8 +5,8 @@ use indexmap::IndexMap;
use shirabe_external_packages::symfony::component::console::input::InputInterface;
use shirabe_external_packages::symfony::component::console::output::OutputInterface;
use shirabe_php_shim::{PhpMixed, strip_tags};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
use crate::console::input::InputOption;
@@ -147,22 +147,23 @@ impl CheckPlatformReqsCommand {
if !candidates.is_empty() {
let mut req_results: Vec<CheckResult> = vec![];
'candidates: for candidate in &candidates {
- let candidate_constraint: Option<Box<dyn ConstraintInterface>> =
+ let candidate_constraint: Option<AnyConstraint> =
if candidate.get_name() == require {
- let mut c = Constraint::new("=", candidate.get_version());
- c.set_pretty_string(Some(
- candidate.get_pretty_version().to_string(),
- ));
- Some(Box::new(c))
+ let c = SimpleConstraint::new(
+ "=".to_string(),
+ candidate.get_version().to_string(),
+ Some(candidate.get_pretty_version().to_string()),
+ );
+ Some(c.into())
} else {
- let mut found: Option<Box<dyn ConstraintInterface>> = None;
+ let mut found: Option<AnyConstraint> = None;
for (_, link) in candidate
.get_provides()
.iter()
.chain(candidate.get_replaces().iter())
{
if link.get_target() == require {
- found = Some(link.get_constraint().clone_box());
+ found = Some(link.get_constraint().clone());
break;
}
}
@@ -175,7 +176,7 @@ impl CheckPlatformReqsCommand {
};
for link in links {
- if !link.get_constraint().matches(&*candidate_constraint) {
+ if !link.get_constraint().matches(&candidate_constraint) {
req_results.push(CheckResult {
platform_package: if candidate.get_name() == require {
candidate.get_pretty_name().to_string()
diff --git a/crates/shirabe/src/command/fund_command.rs b/crates/shirabe/src/command/fund_command.rs
index 233eeaa..82c0c0a 100644
--- a/crates/shirabe/src/command/fund_command.rs
+++ b/crates/shirabe/src/command/fund_command.rs
@@ -9,7 +9,7 @@ use shirabe_external_packages::symfony::component::console::input::InputInterfac
use shirabe_external_packages::symfony::component::console::output::OutputInterface;
use shirabe_external_packages::symfony::console::formatter::OutputFormatter;
use shirabe_php_shim::PhpMixed;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
@@ -64,8 +64,7 @@ impl FundCommand {
);
let mut fundings: IndexMap<String, IndexMap<String, Vec<String>>> = IndexMap::new();
- let mut packages_to_load: IndexMap<String, Option<Box<dyn ConstraintInterface>>> =
- IndexMap::new();
+ let mut packages_to_load: IndexMap<String, Option<AnyConstraint>> = IndexMap::new();
let mut packages_to_load_names: indexmap::IndexSet<String> = indexmap::IndexSet::new();
for package in repo.get_packages() {
if package.as_any().downcast_ref::<AliasPackage>().is_some() {
@@ -73,7 +72,7 @@ impl FundCommand {
}
packages_to_load.insert(
package.get_name().to_string(),
- Some(Box::new(MatchAllConstraint::new())),
+ Some(MatchAllConstraint::new(None).into()),
);
packages_to_load_names.insert(package.get_name().to_string());
}
diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs
index 43d6ee8..fa25fa3 100644
--- a/crates/shirabe/src/command/package_discovery_trait.rs
+++ b/crates/shirabe/src/command/package_discovery_trait.rs
@@ -880,9 +880,12 @@ pub trait PackageDiscoveryTrait {
};
if !link
.get_constraint()
- .matches(&shirabe_semver::constraint::Constraint::new(
- "==",
- platform_pkg.get_version(),
+ .matches(&shirabe_semver::constraint::AnyConstraint::Simple(
+ shirabe_semver::constraint::SimpleConstraint::new(
+ "==".to_string(),
+ platform_pkg.get_version().to_string(),
+ None,
+ ),
))
{
let mut platform_pkg_version = platform_pkg.get_pretty_version().to_string();
diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs
index 3eac2df..8826421 100644
--- a/crates/shirabe/src/command/show_command.rs
+++ b/crates/shirabe/src/command/show_command.rs
@@ -13,7 +13,7 @@ use shirabe_php_shim::{
date, extension_loaded, in_array, realpath, strtolower, version_compare,
};
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
use crate::composer::PartialComposerHandle;
@@ -1486,7 +1486,7 @@ impl ShowCommand {
IndexMap<String, String>,
)> {
let name = strtolower(name);
- let constraint: Option<Box<dyn ConstraintInterface>> = match &version {
+ let constraint: Option<AnyConstraint> = match &version {
PhpMixed::String(s) => Some(self.version_parser.parse_constraints(s)?),
PhpMixed::Null => None,
_ => None, // already a ConstraintInterface
@@ -1514,7 +1514,7 @@ impl ShowCommand {
} else {
repository_set.create_pool_for_package(&name, None)?
};
- let matches = pool.what_provides(&name, constraint.as_deref());
+ let matches = pool.what_provides(&name, constraint.as_ref());
let mut literals: Vec<i64> = Vec::new();
for package in matches.iter() {
// avoid showing the 9999999-dev alias if the default branch has no branch-alias set
diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs
index c4ae890..4096272 100644
--- a/crates/shirabe/src/command/update_command.rs
+++ b/crates/shirabe/src/command/update_command.rs
@@ -178,9 +178,7 @@ impl UpdateCommand {
for (package, constraint) in &reqs {
let package = strtolower(package);
let parsed_constraint = parser.parse_constraints(constraint)?;
- // TODO(phase-b): clone_box because Box<dyn ConstraintInterface> isn't Clone.
- temporary_constraints.insert(package.clone(), parsed_constraint.clone_box());
- let _ = parsed_constraint;
+ temporary_constraints.insert(package.clone(), parsed_constraint);
// TODO(phase-b): access root_requirements[package].getConstraint()
let intersected: bool = todo!("Intervals::haveIntersections check");
if let Some(_root_req) = todo!("root_requirements.get(&package)") as Option<PhpMixed> {
@@ -234,10 +232,9 @@ impl UpdateCommand {
matches.get(1).cloned().unwrap_or_default()
))?;
if temporary_constraints.contains_key(package.get_name()) {
- // TODO(phase-b): Box<dyn ConstraintInterface> isn't Clone; clone_box workaround.
let existing = temporary_constraints
.get(package.get_name())
- .map(|c| c.clone_box())
+ .map(|c| c.clone())
.unwrap();
temporary_constraints.insert(
package.get_name().to_string(),
diff --git a/crates/shirabe/src/dependency_resolver/default_policy.rs b/crates/shirabe/src/dependency_resolver/default_policy.rs
index c24e382..cc33b81 100644
--- a/crates/shirabe/src/dependency_resolver/default_policy.rs
+++ b/crates/shirabe/src/dependency_resolver/default_policy.rs
@@ -5,7 +5,8 @@ use std::cell::RefCell;
use indexmap::IndexMap;
use shirabe_semver::compiling_matcher::CompilingMatcher;
-use shirabe_semver::constraint::Constraint;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::dependency_resolver::PolicyInterface;
use crate::dependency_resolver::Pool;
@@ -209,14 +210,16 @@ impl PolicyInterface for DefaultPolicy {
if (a.is_dev() && a.get_version().starts_with("dev-"))
|| (b.is_dev() && b.get_version().starts_with("dev-"))
{
- let constraint = Constraint::new(operator, b.get_version());
- let version = Constraint::new("==", a.get_version());
+ let constraint =
+ SimpleConstraint::new(operator.to_string(), b.get_version().to_string(), None);
+ let version =
+ SimpleConstraint::new("==".to_string(), a.get_version().to_string(), None);
return constraint.match_specific(&version, true);
}
CompilingMatcher::r#match(
- &Constraint::new(operator, b.get_version()),
- Constraint::OP_EQ,
+ &SimpleConstraint::new(operator.to_string(), b.get_version().to_string(), None).into(),
+ SimpleConstraint::OP_EQ,
a.get_version().to_string(),
)
}
diff --git a/crates/shirabe/src/dependency_resolver/pool.rs b/crates/shirabe/src/dependency_resolver/pool.rs
index e43eb53..771f363 100644
--- a/crates/shirabe/src/dependency_resolver/pool.rs
+++ b/crates/shirabe/src/dependency_resolver/pool.rs
@@ -5,8 +5,8 @@ use std::fmt;
use indexmap::IndexMap;
use shirabe_php_shim::{Countable, STR_PAD_LEFT, abs, spl_object_hash, str_pad};
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::SimpleConstraint;
use crate::advisory::PartialSecurityAdvisory;
use crate::package::BasePackage;
@@ -70,7 +70,7 @@ impl Pool {
pub fn get_removed_versions(
&self,
name: &str,
- constraint: &dyn ConstraintInterface,
+ constraint: &AnyConstraint,
) -> IndexMap<String, String> {
let Some(versions) = self.removed_versions.get(name) else {
return IndexMap::new();
@@ -78,7 +78,9 @@ impl Pool {
let mut result: IndexMap<String, String> = IndexMap::new();
for (version, pretty_version) in versions {
- if constraint.matches(&Constraint::new("==", version)) {
+ if constraint
+ .matches(&SimpleConstraint::new("==".to_string(), version.to_string(), None).into())
+ {
result.insert(version.clone(), pretty_version.clone());
}
}
@@ -110,7 +112,7 @@ impl Pool {
pub fn is_security_removed_package_version(
&self,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> bool {
let empty = IndexMap::new();
let versions = self
@@ -119,7 +121,9 @@ impl Pool {
.unwrap_or(&empty);
for (version, _package_with_security_advisories) in versions {
if let Some(c) = constraint {
- if c.matches(&Constraint::new("==", version)) {
+ if c.matches(
+ &SimpleConstraint::new("==".to_string(), version.to_string(), None).into(),
+ ) {
return true;
}
}
@@ -132,7 +136,7 @@ impl Pool {
pub fn get_security_advisory_identifiers_for_package_version(
&self,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> Vec<String> {
let empty = IndexMap::new();
let versions = self
@@ -141,7 +145,9 @@ impl Pool {
.unwrap_or(&empty);
for (version, package_with_security_advisories) in versions {
if let Some(c) = constraint {
- if c.matches(&Constraint::new("==", version)) {
+ if c.matches(
+ &SimpleConstraint::new("==".to_string(), version.to_string(), None).into(),
+ ) {
return package_with_security_advisories
.iter()
.map(|advisory| advisory.advisory_id.clone())
@@ -156,7 +162,7 @@ impl Pool {
pub fn is_abandoned_removed_package_version(
&self,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> bool {
let empty = IndexMap::new();
let versions = self
@@ -165,7 +171,9 @@ impl Pool {
.unwrap_or(&empty);
for (version, _pretty_version) in versions {
if let Some(c) = constraint {
- if c.matches(&Constraint::new("==", version)) {
+ if c.matches(
+ &SimpleConstraint::new("==".to_string(), version.to_string(), None).into(),
+ ) {
return true;
}
}
@@ -226,11 +234,11 @@ impl Pool {
pub fn what_provides(
&mut self,
name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> Vec<Box<dyn BasePackage>> {
// PHP: $key = (string) $constraint;
let key = match constraint {
- Some(c) => c.__to_string(),
+ Some(c) => c.to_string(),
None => String::new(),
};
if let Some(by_key) = self.provider_cache.get(name) {
@@ -254,7 +262,7 @@ impl Pool {
pub(crate) fn compute_what_provides(
&self,
name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> Vec<Box<dyn BasePackage>> {
let Some(candidates) = self.package_by_name.get(name) else {
return vec![];
@@ -306,7 +314,7 @@ impl Pool {
&self,
candidate: &dyn BasePackage,
name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> bool {
let candidate_name = candidate.get_name();
let candidate_version = candidate.get_version();
@@ -315,7 +323,7 @@ impl Pool {
return constraint.is_none()
|| CompilingMatcher::r#match(
constraint.unwrap(),
- Constraint::OP_EQ,
+ SimpleConstraint::OP_EQ,
candidate_version.to_string(),
);
}
diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs
index fcc0339..f80ef38 100644
--- a/crates/shirabe/src/dependency_resolver/pool_builder.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs
@@ -11,10 +11,10 @@ use shirabe_php_shim::{
array_search, array_search_mixed, count, in_array, microtime, number_format, round,
spl_object_hash, sprintf, strpos,
};
-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::dependency_resolver::Pool;
use crate::dependency_resolver::PoolOptimizer;
@@ -41,13 +41,13 @@ pub struct PoolBuilder {
stability_flags: IndexMap<String, i64>,
root_aliases: IndexMap<String, IndexMap<String, IndexMap<String, String>>>,
root_references: IndexMap<String, String>,
- temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>,
+ temporary_constraints: IndexMap<String, AnyConstraint>,
event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
pool_optimizer: Option<PoolOptimizer>,
io: Box<dyn IOInterface>,
alias_map: IndexMap<String, IndexMap<i64, AliasPackage>>,
- packages_to_load: IndexMap<String, Box<dyn ConstraintInterface>>,
- loaded_packages: IndexMap<String, Box<dyn ConstraintInterface>>,
+ packages_to_load: IndexMap<String, AnyConstraint>,
+ loaded_packages: IndexMap<String, AnyConstraint>,
loaded_per_repo: IndexMap<i64, IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>>,
packages: IndexMap<i64, Box<dyn BasePackage>>,
unacceptable_fixed_or_locked_packages: Vec<Box<dyn BasePackage>>,
@@ -88,7 +88,7 @@ impl PoolBuilder {
io: Box<dyn IOInterface>,
event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
pool_optimizer: Option<PoolOptimizer>,
- temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>,
+ temporary_constraints: IndexMap<String, AnyConstraint>,
security_advisory_pool_filter: Option<SecurityAdvisoryPoolFilter>,
) -> Self {
Self {
@@ -195,14 +195,14 @@ impl PoolBuilder {
// loading any packages
self.loaded_packages.insert(
package.get_name().to_string(),
- Box::new(MatchAllConstraint::new()),
+ MatchAllConstraint::new(None).into(),
);
// replace means conflict, so if a fixed package replaces a name, no need to load that one, packages would conflict anyways
for (_k, link) in &package.get_replaces() {
self.loaded_packages.insert(
link.get_target().to_string(),
- Box::new(MatchAllConstraint::new()),
+ MatchAllConstraint::new(None).into(),
);
}
@@ -238,7 +238,7 @@ impl PoolBuilder {
}
self.packages_to_load
- .insert(package_name.clone(), constraint.clone_box());
+ .insert(package_name.clone(), constraint.clone());
self.max_extended_reqs.insert(package_name.clone(), true);
}
@@ -271,7 +271,7 @@ impl PoolBuilder {
for package_name in package.get_names(true) {
let constraint = match self.temporary_constraints.get(&package_name) {
- Some(c) => c.clone_box(),
+ Some(c) => c.clone(),
None => continue,
};
@@ -288,7 +288,8 @@ impl PoolBuilder {
let mut found = false;
for (_idx, version) in &package_and_aliases {
- if CompilingMatcher::matches(&*constraint, Constraint::OP_EQ, version) {
+ if CompilingMatcher::matches(&constraint, SimpleConstraint::OP_EQ, version)
+ {
found = true;
}
}
@@ -377,9 +378,9 @@ impl PoolBuilder {
&mut self,
request: &Request,
name: &str,
- constraint: &dyn ConstraintInterface,
+ constraint: &AnyConstraint,
) {
- let constraint = constraint.clone_box();
+ let constraint = constraint.clone();
// Skip platform requires at this stage
if PlatformRepository::is_platform_package(name) {
return;
@@ -398,8 +399,8 @@ impl PoolBuilder {
let root_requires = request.get_requires();
let mut constraint = constraint;
if let Some(root_constraint) = root_requires.get(name) {
- if !Intervals::is_subset_of(&*constraint, &**root_constraint).unwrap_or(false) {
- constraint = root_constraint.clone_box();
+ if !Intervals::is_subset_of(&constraint, root_constraint).unwrap_or(false) {
+ constraint = root_constraint.clone();
}
}
@@ -410,17 +411,18 @@ impl PoolBuilder {
// MultiConstraint::create() will optimize anyway)
if let Some(existing) = self.packages_to_load.get(name) {
// Already marked for loading and this does not expand the constraint to be loaded, nothing to do
- if Intervals::is_subset_of(&*constraint, &**existing).unwrap_or(false) {
+ if Intervals::is_subset_of(&constraint, existing).unwrap_or(false) {
return;
}
// extend the constraint to be loaded
constraint = Intervals::compact_constraint(
MultiConstraint::create(
- vec![existing.clone_box(), constraint.clone_box()],
+ vec![existing.clone(), constraint.clone()],
false,
+ None,
)
- .unwrap_or_else(|_| Box::new(MatchAllConstraint::new())),
+ .unwrap_or_else(|_| MatchAllConstraint::new(None).into()),
);
}
@@ -431,7 +433,7 @@ impl PoolBuilder {
// No need to load this package with this constraint because it is
// a subset of the constraint with which we have already loaded packages
- if Intervals::is_subset_of(&*constraint, &**self.loaded_packages.get(name).unwrap())
+ if Intervals::is_subset_of(&constraint, self.loaded_packages.get(name).unwrap())
.unwrap_or(false)
{
return;
@@ -444,13 +446,11 @@ impl PoolBuilder {
name.to_string(),
Intervals::compact_constraint(
MultiConstraint::create(
- vec![
- self.loaded_packages.get(name).unwrap().clone_box(),
- constraint,
- ],
+ vec![self.loaded_packages.get(name).unwrap().clone(), constraint],
false,
+ None,
)
- .unwrap_or_else(|_| Box::new(MatchAllConstraint::new())),
+ .unwrap_or_else(|_| MatchAllConstraint::new(None).into()),
),
);
self.loaded_packages.shift_remove(name);
@@ -475,23 +475,23 @@ impl PoolBuilder {
for name in to_remove {
self.packages_to_load.shift_remove(&name);
}
- let snapshot: Vec<(String, Box<dyn ConstraintInterface>)> = self
+ let snapshot: Vec<(String, AnyConstraint)> = self
.packages_to_load
.iter()
- .map(|(k, v)| (k.clone(), v.clone_box()))
+ .map(|(k, v)| (k.clone(), v.clone()))
.collect();
for (name, constraint) in &snapshot {
self.loaded_packages
- .insert(name.clone(), constraint.clone_box());
+ .insert(name.clone(), constraint.clone());
}
// Load packages in chunks of 50 to prevent memory usage build-up due to caches of all sorts
// TODO(phase-b): array_chunk shim signature expects &[T]; build IndexMap chunks manually.
- let mut package_batches: Vec<IndexMap<String, Box<dyn ConstraintInterface>>> = {
- let mut chunks: Vec<IndexMap<String, Box<dyn ConstraintInterface>>> = Vec::new();
- let mut current: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut package_batches: Vec<IndexMap<String, AnyConstraint>> = {
+ let mut chunks: Vec<IndexMap<String, AnyConstraint>> = Vec::new();
+ let mut current: IndexMap<String, AnyConstraint> = IndexMap::new();
for (k, v) in self.packages_to_load.iter() {
- current.insert(k.clone(), v.clone_box());
+ current.insert(k.clone(), v.clone());
if current.len() as i64 >= Self::LOAD_BATCH_SIZE {
chunks.push(std::mem::take(&mut current));
}
@@ -525,11 +525,11 @@ impl PoolBuilder {
// Iterate by index because we mutate package_batches inside the loop.
for batch_index in 0..package_batches.len() {
- let package_batch: IndexMap<String, Option<Box<dyn ConstraintInterface>>> =
- package_batches[batch_index]
- .iter()
- .map(|(k, v)| (k.clone(), Some(v.clone_box())))
- .collect();
+ let package_batch: IndexMap<String, Option<AnyConstraint>> = package_batches
+ [batch_index]
+ .iter()
+ .map(|(k, v)| (k.clone(), Some(v.clone())))
+ .collect();
let result = repository.load_packages(
package_batch,
self.acceptable_stabilities.clone(),
@@ -598,18 +598,18 @@ impl PoolBuilder {
}
// PHP: array_chunk(array_merge(...$packageBatches), self::LOAD_BATCH_SIZE, true)
- let mut merged: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut merged: IndexMap<String, AnyConstraint> = IndexMap::new();
for batch in &package_batches {
for (k, v) in batch {
- merged.insert(k.clone(), v.clone_box());
+ merged.insert(k.clone(), v.clone());
}
}
// Rebuild chunks from merged.
package_batches = {
- let mut chunks: Vec<IndexMap<String, Box<dyn ConstraintInterface>>> = Vec::new();
- let mut current: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut chunks: Vec<IndexMap<String, AnyConstraint>> = Vec::new();
+ let mut current: IndexMap<String, AnyConstraint> = IndexMap::new();
for (k, v) in merged.iter() {
- current.insert(k.clone(), v.clone_box());
+ current.insert(k.clone(), v.clone());
if current.len() as i64 >= Self::LOAD_BATCH_SIZE {
chunks.push(std::mem::take(&mut current));
}
@@ -929,7 +929,7 @@ impl PoolBuilder {
self.mark_package_name_for_loading(
request,
&replacer_name,
- &MatchAllConstraint::new(),
+ &MatchAllConstraint::new(None).into(),
);
} else {
let pkgs: Vec<Box<dyn BasePackage>> =
@@ -1050,8 +1050,8 @@ impl PoolBuilder {
fn mark_package_name_for_loading_if_required(&mut self, request: &Request, name: &str) {
if self.is_root_require(request, name) {
- let cons = request.get_requires()[name].clone_box();
- self.mark_package_name_for_loading(request, name, &*cons);
+ let cons = request.get_requires()[name].clone();
+ self.mark_package_name_for_loading(request, name, &cons);
}
let pkgs: Vec<Box<dyn BasePackage>> =
diff --git a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
index 326587a..27b3ffb 100644
--- a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
@@ -6,9 +6,9 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_php_shim::{LogicException, PhpMixed, implode, ksort, spl_object_hash};
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::MultiConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use shirabe_semver::intervals::Intervals;
use crate::dependency_resolver::PolicyInterface;
@@ -29,12 +29,10 @@ pub struct PoolOptimizer {
irremovable_packages: IndexMap<i64, bool>,
/// @var array<string, array<string, ConstraintInterface>>
- require_constraints_per_package:
- IndexMap<String, IndexMap<String, Box<dyn ConstraintInterface>>>,
+ require_constraints_per_package: IndexMap<String, IndexMap<String, AnyConstraint>>,
/// @var array<string, array<string, ConstraintInterface>>
- conflict_constraints_per_package:
- IndexMap<String, IndexMap<String, Box<dyn ConstraintInterface>>>,
+ conflict_constraints_per_package: IndexMap<String, IndexMap<String, AnyConstraint>>,
/// @var array<int, true>
packages_to_remove: IndexMap<i64, bool>,
@@ -90,23 +88,27 @@ impl PoolOptimizer {
}
fn prepare(&mut self, request: &Request, pool: &Pool) {
- let mut irremovable_package_constraint_groups: IndexMap<
- String,
- Vec<Box<dyn ConstraintInterface>>,
- > = IndexMap::new();
+ let mut irremovable_package_constraint_groups: IndexMap<String, Vec<AnyConstraint>> =
+ IndexMap::new();
// Mark fixed or locked packages as irremovable
for (_, package) in request.get_fixed_or_locked_packages() {
irremovable_package_constraint_groups
.entry(PackageInterface::get_name(package.as_ref()).to_string())
.or_insert_with(Vec::new)
- .push(Box::new(Constraint::new("==", package.get_version())));
+ .push(
+ SimpleConstraint::new(
+ "==".to_string(),
+ package.get_version().to_string(),
+ None,
+ )
+ .into(),
+ );
}
// Extract requested package requirements
for (require, constraint) in request.get_requires() {
- // TODO(phase-b): clone Box<dyn ConstraintInterface>
- self.extract_require_constraints_per_package(require, todo!("constraint.clone_box()"));
+ self.extract_require_constraints_per_package(require, constraint.clone());
}
// First pass over all packages to extract information and mark package constraints irremovable
@@ -115,16 +117,14 @@ impl PoolOptimizer {
for link in package.get_requires().values() {
self.extract_require_constraints_per_package(
link.get_target(),
- // TODO(phase-b): clone constraint
- todo!("link.get_constraint().clone_box()"),
+ link.get_constraint().clone(),
);
}
// Extract package conflicts
for link in package.get_conflicts().values() {
self.extract_conflict_constraints_per_package(
link.get_target(),
- // TODO(phase-b): clone constraint
- todo!("link.get_constraint().clone_box()"),
+ link.get_constraint().clone(),
);
}
@@ -138,16 +138,14 @@ impl PoolOptimizer {
}
}
- let mut irremovable_package_constraints: IndexMap<String, Box<dyn ConstraintInterface>> =
- IndexMap::new();
+ let mut irremovable_package_constraints: IndexMap<String, AnyConstraint> = IndexMap::new();
for (package_name, constraints) in irremovable_package_constraint_groups {
- // TODO(phase-b): MultiConstraint::new signature; move ownership of constraints vec
irremovable_package_constraints.insert(
package_name,
if 1 == constraints.len() {
- todo!("constraints[0] moved out")
+ constraints.into_iter().next().unwrap()
} else {
- Box::new(MultiConstraint::new(constraints, false))
+ MultiConstraint::new(constraints, false, None).into()
},
);
}
@@ -165,8 +163,8 @@ impl PoolOptimizer {
.get(PackageInterface::get_name(package.as_ref()))
.unwrap();
if CompilingMatcher::r#match(
- constraint.as_ref(),
- Constraint::OP_EQ,
+ constraint,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
self.mark_package_irremovable(package.as_ref());
@@ -262,8 +260,8 @@ impl PoolOptimizer {
let mut group_hash_parts: Vec<String> = vec![];
if CompilingMatcher::r#match(
- require_constraint.as_ref(),
- Constraint::OP_EQ,
+ require_constraint,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
group_hash_parts.push(format!(
@@ -276,7 +274,7 @@ impl PoolOptimizer {
for (_, link) in package.get_replaces() {
if CompilingMatcher::r#match(
link.get_constraint(),
- Constraint::OP_EQ,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
// Use the same hash part as the regular require hash because that's what the replacement does
@@ -293,8 +291,8 @@ impl PoolOptimizer {
{
for (_, conflict_constraint) in conflict_constraints {
if CompilingMatcher::r#match(
- conflict_constraint.as_ref(),
- Constraint::OP_EQ,
+ conflict_constraint,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
group_hash_parts.push(format!(
@@ -415,7 +413,7 @@ impl PoolOptimizer {
// performance more than the additional few packages that could be filtered out would benefit the process.
subhash.insert(
link.get_target().to_string(),
- link.get_constraint().__to_string(),
+ link.get_constraint().to_string(),
);
}
@@ -638,7 +636,7 @@ impl PoolOptimizer {
if false
== CompilingMatcher::r#match(
link_constraint,
- Constraint::OP_EQ,
+ SimpleConstraint::OP_EQ,
version_str,
)
{
@@ -662,13 +660,13 @@ impl PoolOptimizer {
fn extract_require_constraints_per_package(
&mut self,
package: &str,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
) {
for expanded in self.expand_disjunctive_multi_constraints(constraint) {
self.require_constraints_per_package
.entry(package.to_string())
.or_insert_with(IndexMap::new)
- .insert(expanded.__to_string(), expanded);
+ .insert(expanded.to_string(), expanded);
}
}
@@ -680,32 +678,28 @@ impl PoolOptimizer {
fn extract_conflict_constraints_per_package(
&mut self,
package: &str,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
) {
for expanded in self.expand_disjunctive_multi_constraints(constraint) {
self.conflict_constraints_per_package
.entry(package.to_string())
.or_insert_with(IndexMap::new)
- .insert(expanded.__to_string(), expanded);
+ .insert(expanded.to_string(), expanded);
}
}
/// @return ConstraintInterface[]
fn expand_disjunctive_multi_constraints(
&self,
- constraint: Box<dyn ConstraintInterface>,
- ) -> Vec<Box<dyn ConstraintInterface>> {
- let constraint = Intervals::compact_constraint(&*constraint).unwrap_or(constraint);
+ constraint: AnyConstraint,
+ ) -> Vec<AnyConstraint> {
+ let constraint = Intervals::compact_constraint(&constraint).unwrap_or(constraint);
- if let Some(multi) = constraint.as_any().downcast_ref::<MultiConstraint>() {
- if multi.is_disjunctive() {
+ if let Some(multi) = constraint.as_multi_constraint() {
+ if multi.is_disjunctive_mc() {
// No need to call ourselves recursively here because Intervals::compactConstraint() ensures that there
// are no nested disjunctive MultiConstraint instances possible
- return multi
- .get_constraints()
- .iter()
- .map(|c| c.clone_box())
- .collect();
+ return multi.get_constraints().iter().map(|c| c.clone()).collect();
}
}
diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs
index a69a4a2..4436ec8 100644
--- a/crates/shirabe/src/dependency_resolver/problem.rs
+++ b/crates/shirabe/src/dependency_resolver/problem.rs
@@ -9,9 +9,9 @@ use shirabe_php_shim::{
phpversion, spl_object_hash, sprintf, str_replace, str_starts_with, stripos, strpos,
strtolower, substr, substr_count, version_compare,
};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MultiConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::advisory::SecurityAdvisory;
use crate::dependency_resolver::Pool;
@@ -92,14 +92,13 @@ impl Problem {
let reason_data = rule_ref.get_reason_data();
// TODO(phase-b): reason_data for RULE_ROOT_REQUIRE; extract via ReasonData::RootRequire variant.
- let (package_name, constraint): (String, Option<&dyn ConstraintInterface>) =
- match reason_data {
- rule::ReasonData::RootRequire {
- package_name,
- constraint,
- } => (package_name.clone(), Some(constraint.as_ref())),
- _ => (String::new(), None),
- };
+ let (package_name, constraint): (String, Option<&AnyConstraint>) = match reason_data {
+ rule::ReasonData::RootRequire {
+ package_name,
+ constraint,
+ } => (package_name.clone(), Some(constraint)),
+ _ => (String::new(), None),
+ };
let packages = pool.compute_what_provides(&package_name, constraint);
if packages.len() == 0 {
@@ -393,7 +392,7 @@ impl Problem {
pool: &mut Pool,
is_verbose: bool,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> (String, String) {
if PlatformRepository::is_platform_package(package_name) {
// handle php/php-*/hhvm
@@ -572,7 +571,7 @@ impl Problem {
if let Some(c) = constraint {
if c.is_constraint()
- && c.get_operator() == Constraint::STR_OP_EQ
+ && c.get_operator() == SimpleConstraint::STR_OP_EQ
&& Preg::is_match3(r"{^dev-.*#.*}", &c.get_pretty_string(), None).unwrap_or(false)
{
let new_constraint =
@@ -580,17 +579,25 @@ impl Problem {
.unwrap_or_else(|_| c.get_pretty_string());
let packages = repository_set.find_packages(
package_name,
- Some(Box::new(MultiConstraint::new(
- vec![
- Box::new(Constraint::new(Constraint::STR_OP_EQ, &new_constraint))
- as Box<dyn ConstraintInterface>,
- Box::new(Constraint::new(
- Constraint::STR_OP_EQ,
- &str_replace("#", "+", &new_constraint),
- )) as Box<dyn ConstraintInterface>,
- ],
- false,
- ))),
+ Some(
+ MultiConstraint::new(
+ vec![
+ AnyConstraint::Simple(SimpleConstraint::new(
+ SimpleConstraint::STR_OP_EQ.to_string(),
+ new_constraint.clone(),
+ None,
+ )),
+ AnyConstraint::Simple(SimpleConstraint::new(
+ SimpleConstraint::STR_OP_EQ.to_string(),
+ str_replace("#", "+", &new_constraint),
+ None,
+ )),
+ ],
+ false,
+ None,
+ )
+ .into(),
+ ),
0,
);
if packages.len() > 0 {
@@ -618,15 +625,21 @@ impl Problem {
// first check if the actual requested package is found in normal conditions
// if so it must mean it is rejected by another constraint than the one given here
- let packages =
- repository_set.find_packages(package_name, constraint.map(|c| c.clone_box()), 0);
+ let packages = repository_set.find_packages(package_name, constraint.map(|c| c.clone()), 0);
if packages.len() > 0 {
let root_reqs = repository_set.get_root_requires();
if root_reqs.contains_key(package_name) {
let filtered: Vec<&Box<dyn BasePackage>> = packages
.iter()
.filter(|p| {
- root_reqs[package_name].matches(&Constraint::new("==", p.get_version()))
+ root_reqs[package_name].matches(
+ &SimpleConstraint::new(
+ "==".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ )
})
.collect();
if filtered.len() == 0 {
@@ -663,7 +676,14 @@ impl Problem {
let filtered: Vec<&Box<dyn BasePackage>> = packages
.iter()
.filter(|p| {
- temp_reqs[&name].matches(&Constraint::new("==", p.get_version()))
+ temp_reqs[&name].matches(
+ &SimpleConstraint::new(
+ "==".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ )
})
.collect();
if filtered.len() == 0 {
@@ -696,10 +716,23 @@ impl Problem {
}
if let Some(ref lp) = locked_package {
- let fixed_constraint = Constraint::new("==", lp.get_version());
+ let fixed_constraint = AnyConstraint::from(SimpleConstraint::new(
+ "==".to_string(),
+ lp.get_version().to_string(),
+ None,
+ ));
let filtered: Vec<&Box<dyn BasePackage>> = packages
.iter()
- .filter(|p| fixed_constraint.matches(&Constraint::new("==", p.get_version())))
+ .filter(|p| {
+ fixed_constraint.matches(
+ &SimpleConstraint::new(
+ "==".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ )
+ })
.collect();
if filtered.len() == 0 {
return (
@@ -837,14 +870,14 @@ impl Problem {
// check if the package is found when bypassing stability checks
let packages = repository_set.find_packages(
package_name,
- constraint.map(|c| c.clone_box()),
+ constraint.map(|c| c.clone()),
RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES,
);
if packages.len() > 0 {
// we must first verify if a valid package would be found in a lower priority repository
let all_repos_packages = repository_set.find_packages(
package_name,
- constraint.map(|c| c.clone_box()),
+ constraint.map(|c| c.clone()),
RepositorySet::ALLOW_SHADOWED_REPOSITORIES,
);
if all_repos_packages.len() > 0 {
@@ -887,7 +920,7 @@ impl Problem {
// we must first verify if a valid package would be found in a lower priority repository
let all_repos_packages = repository_set.find_packages(
package_name,
- constraint.map(|c| c.clone_box()),
+ constraint.map(|c| c.clone()),
RepositorySet::ALLOW_SHADOWED_REPOSITORIES,
);
if all_repos_packages.len() > 0 {
@@ -993,7 +1026,7 @@ impl Problem {
packages: &Vec<Box<dyn BasePackage>>,
is_verbose: bool,
pool: Option<&Pool>,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
use_removed_version_group: bool,
) -> String {
struct PreparedEntry {
@@ -1213,7 +1246,7 @@ impl Problem {
higher_repo_packages: &Vec<Box<dyn BasePackage>>,
all_repos_packages: &Vec<Box<dyn BasePackage>>,
reason: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> (String, String) {
let mut next_repo_packages: Vec<Box<dyn BasePackage>> = Vec::new();
let mut next_repo: Option<Box<dyn crate::repository::RepositoryInterface>> = None;
@@ -1346,10 +1379,10 @@ impl Problem {
}
/// Turns a constraint into text usable in a sentence describing a request
- pub(crate) fn constraint_to_text(constraint: Option<&dyn ConstraintInterface>) -> String {
+ pub(crate) fn constraint_to_text(constraint: Option<&AnyConstraint>) -> String {
if let Some(c) = constraint {
if c.is_constraint()
- && c.get_operator() == Constraint::STR_OP_EQ
+ && c.get_operator() == SimpleConstraint::STR_OP_EQ
&& !str_starts_with(&c.get_version(), "dev-")
{
if !Preg::is_match3(r"{^\d+(?:\.\d+)*$}", &c.get_pretty_string(), None)
diff --git a/crates/shirabe/src/dependency_resolver/request.rs b/crates/shirabe/src/dependency_resolver/request.rs
index d181bd2..e2bfc3c 100644
--- a/crates/shirabe/src/dependency_resolver/request.rs
+++ b/crates/shirabe/src/dependency_resolver/request.rs
@@ -2,7 +2,7 @@
use indexmap::IndexMap;
use shirabe_php_shim::{LogicException, spl_object_hash, strtolower};
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
use crate::package::BasePackage;
@@ -43,7 +43,7 @@ pub enum UpdateAllowTransitiveDeps {
#[derive(Debug)]
pub struct Request {
pub(crate) locked_repository: Option<LockArrayRepository>,
- pub(crate) requires: IndexMap<String, Box<dyn ConstraintInterface>>,
+ pub(crate) requires: IndexMap<String, AnyConstraint>,
pub(crate) fixed_packages: IndexMap<String, Box<dyn BasePackage>>,
pub(crate) locked_packages: IndexMap<String, Box<dyn BasePackage>>,
pub(crate) fixed_locked_packages: IndexMap<String, Box<dyn BasePackage>>,
@@ -69,10 +69,10 @@ impl Request {
pub fn require_name(
&mut self,
package_name: &str,
- constraint: Option<Box<dyn ConstraintInterface>>,
+ constraint: Option<AnyConstraint>,
) -> anyhow::Result<()> {
let package_name = strtolower(package_name);
- let constraint = constraint.unwrap_or_else(|| Box::new(MatchAllConstraint::new()));
+ let constraint = constraint.unwrap_or_else(|| MatchAllConstraint::new(None).into());
if self.requires.contains_key(&package_name) {
return Err(LogicException {
message: format!(
@@ -155,7 +155,7 @@ impl Request {
== UpdateAllowTransitiveDeps::UpdateListedWithTransitiveDeps
}
- pub fn get_requires(&self) -> &IndexMap<String, Box<dyn ConstraintInterface>> {
+ pub fn get_requires(&self) -> &IndexMap<String, AnyConstraint> {
&self.requires
}
diff --git a/crates/shirabe/src/dependency_resolver/rule.rs b/crates/shirabe/src/dependency_resolver/rule.rs
index 90223e2..fbc8521 100644
--- a/crates/shirabe/src/dependency_resolver/rule.rs
+++ b/crates/shirabe/src/dependency_resolver/rule.rs
@@ -10,8 +10,8 @@ use shirabe_php_shim::{
LogicException, PhpMixed, RuntimeException, abs, array_filter, array_keys, array_shift,
array_values, implode, is_object,
};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::dependency_resolver::GenericRule;
use crate::dependency_resolver::MultiConflictRule;
@@ -36,7 +36,7 @@ pub enum ReasonData {
Int(i64),
RootRequire {
package_name: String,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
},
Fixed {
package: Box<dyn BasePackage>,
@@ -238,10 +238,14 @@ impl Rule {
if pool.is_unacceptable_fixed_or_locked_package(p) {
return true;
}
- if !link
- .get_constraint()
- .matches(&Constraint::new("=", p.get_version()))
- {
+ if !link.get_constraint().matches(
+ &SimpleConstraint::new(
+ "=".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ ) {
return true;
}
// required package was locked but has been unlocked and still matches
@@ -275,7 +279,14 @@ impl Rule {
if pool.is_unacceptable_fixed_or_locked_package(p) {
return true;
}
- if !constraint.matches(&Constraint::new("=", p.get_version())) {
+ if !constraint.matches(
+ &SimpleConstraint::new(
+ "=".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ ) {
return true;
}
break;
@@ -345,12 +356,11 @@ impl Rule {
match self.get_reason() {
r if r == RULE_ROOT_REQUIRE => {
let reason_data = self.get_reason_data();
- let (package_name, constraint): (&str, &dyn ConstraintInterface) = match reason_data
- {
+ let (package_name, constraint): (&str, &AnyConstraint) = match reason_data {
ReasonData::RootRequire {
package_name,
constraint,
- } => (package_name.as_str(), constraint.as_ref()),
+ } => (package_name.as_str(), constraint),
_ => return String::new(),
};
@@ -712,7 +722,7 @@ impl Rule {
pool: &Pool,
packages: Vec<Box<dyn BasePackage>>,
is_verbose: bool,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
use_removed_version_group: bool,
) -> String {
Problem::get_package_list(
@@ -730,7 +740,7 @@ impl Rule {
pool: &Pool,
literals: &[i64],
is_verbose: bool,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
use_removed_version_group: bool,
) -> String {
let mut packages: Vec<Box<dyn BasePackage>> = vec![];
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
index 45f1331..076ce42 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
@@ -205,14 +205,14 @@ impl RuleSetGenerator {
}
for link in package.get_requires().values() {
- let mut constraint = link.get_constraint().clone_box();
+ let mut constraint = link.get_constraint().clone();
if platform_requirement_filter.is_ignored(link.get_target()) {
continue;
} else if let Some(ignore_list_filter) = platform_requirement_filter
.as_any()
.downcast_ref::<IgnoreListPlatformRequirementFilter>(
) {
- let fallback = constraint.clone_box();
+ let fallback = constraint.clone();
constraint = ignore_list_filter
.filter_constraint(link.get_target(), constraint, true)
.unwrap_or(fallback);
@@ -221,7 +221,7 @@ impl RuleSetGenerator {
let possible_requires: Vec<Box<dyn PackageInterface>> = self
.pool
.borrow_mut()
- .what_provides(link.get_target(), Some(&*constraint))
+ .what_provides(link.get_target(), Some(&constraint))
.into_iter()
.map(|p| p.clone_package_box())
.collect();
@@ -258,14 +258,14 @@ impl RuleSetGenerator {
continue;
}
- let mut constraint = link.get_constraint().clone_box();
+ let mut constraint = link.get_constraint().clone();
if platform_requirement_filter.is_ignored(link.get_target()) {
continue;
} else if let Some(ignore_list_filter) = platform_requirement_filter
.as_any()
.downcast_ref::<IgnoreListPlatformRequirementFilter>(
) {
- let fallback = constraint.clone_box();
+ let fallback = constraint.clone();
constraint = ignore_list_filter
.filter_constraint(link.get_target(), constraint, false)
.unwrap_or(fallback);
@@ -274,7 +274,7 @@ impl RuleSetGenerator {
let conflicts = self
.pool
.borrow_mut()
- .what_provides(link.get_target(), Some(&*constraint));
+ .what_provides(link.get_target(), Some(&constraint));
for conflict in &conflicts {
// define the conflict rule for regular packages, for alias packages it's only needed if the name
@@ -354,14 +354,14 @@ impl RuleSetGenerator {
}
for (package_name, constraint) in request.get_requires() {
- let mut constraint = constraint.clone_box();
+ let mut constraint = constraint.clone();
if platform_requirement_filter.is_ignored(package_name) {
continue;
} else if let Some(ignore_list_filter) = platform_requirement_filter
.as_any()
.downcast_ref::<IgnoreListPlatformRequirementFilter>(
) {
- let fallback = constraint.clone_box();
+ let fallback = constraint.clone();
constraint = ignore_list_filter
.filter_constraint(package_name, constraint, true)
.unwrap_or(fallback);
@@ -370,7 +370,7 @@ impl RuleSetGenerator {
let packages: Vec<Box<dyn PackageInterface>> = self
.pool
.borrow_mut()
- .what_provides(package_name, Some(&*constraint))
+ .what_provides(package_name, Some(&constraint))
.into_iter()
.map(|p| p.clone_package_box())
.collect();
diff --git a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
index 742a709..4daf641 100644
--- a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
+++ b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
@@ -8,7 +8,8 @@ use crate::dependency_resolver::Request;
use crate::package::PackageInterface;
use crate::repository::RepositoryInterface;
use indexmap::IndexMap;
-use shirabe_semver::constraint::Constraint;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
#[derive(Debug)]
pub struct SecurityAdvisoryPoolFilter {
@@ -64,7 +65,9 @@ impl SecurityAdvisoryPoolFilter {
continue;
}
- let package_constraint = Constraint::new("==", package.get_version());
+ let package_constraint =
+ SimpleConstraint::new("==".to_string(), package.get_version().to_string(), None)
+ .into();
for advisory in &advisory_map[&package_name] {
// advisory is PartialSecurityAdvisory or SecurityAdvisory; both have affected_versions: Box<dyn ConstraintInterface>
if advisory.affected_versions.matches(&package_constraint) {
diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs
index e4539d2..820f792 100644
--- a/crates/shirabe/src/dependency_resolver/solver.rs
+++ b/crates/shirabe/src/dependency_resolver/solver.rs
@@ -8,7 +8,7 @@ use indexmap::IndexMap;
use shirabe_php_shim::{
PhpMixed, array_pop, array_shift, array_unshift, microtime, spl_object_hash, sprintf,
};
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use crate::dependency_resolver::Decisions;
use crate::dependency_resolver::GenericRule;
@@ -189,8 +189,8 @@ impl Solver {
// TODO(phase-b): ConstraintInterface is a PHP class — Box<dyn ConstraintInterface>
// cannot be cloned. We borrow the original constraint and only allocate a fresh
// box when the ignore filter rewrites it.
- let mut filtered: Option<Box<dyn ConstraintInterface>> = None;
- let constraint_ref: &dyn ConstraintInterface = constraint.as_ref();
+ let mut filtered: Option<AnyConstraint> = None;
+ let constraint_ref: &AnyConstraint = constraint;
if platform_requirement_filter.is_ignored(package_name) {
continue;
} else if let Some(ignore_filter) = platform_requirement_filter
@@ -204,8 +204,7 @@ impl Solver {
let _ = &mut filtered;
}
- let active_constraint: &dyn ConstraintInterface =
- filtered.as_deref().unwrap_or(constraint_ref);
+ let active_constraint: &AnyConstraint = filtered.as_ref().unwrap_or(constraint_ref);
if self
.pool
diff --git a/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs b/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs
index f6b8091..d69773c 100644
--- a/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs
+++ b/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php
use shirabe_external_packages::composer::pcre::Preg;
-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 shirabe_semver::interval::Interval;
use shirabe_semver::intervals::Intervals;
@@ -41,9 +41,9 @@ impl IgnoreListPlatformRequirementFilter {
pub fn filter_constraint(
&self,
req: &str,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
allow_upper_bound_override: bool,
- ) -> anyhow::Result<Box<dyn ConstraintInterface>> {
+ ) -> anyhow::Result<AnyConstraint> {
if !PlatformRepository::is_platform_package(req) {
return Ok(constraint);
}
@@ -53,20 +53,26 @@ impl IgnoreListPlatformRequirementFilter {
}
if Preg::is_match(&self.ignore_regex, req)? {
- return Ok(Box::new(MatchAllConstraint::new()));
+ return Ok(MatchAllConstraint::new(None).into());
}
- let intervals = Intervals::get(&*constraint)?;
+ let intervals = Intervals::get(&constraint)?;
let last = intervals.numeric.last();
if let Some(last) = last {
if last.get_end().to_string() != Interval::until_positive_infinity().to_string() {
- let constraint = Box::new(MultiConstraint::new(
+ let constraint = MultiConstraint::new(
vec![
constraint,
- Box::new(Constraint::new(">=", last.get_end().get_version())),
+ AnyConstraint::Simple(SimpleConstraint::new(
+ ">=".to_string(),
+ last.get_end().get_version().to_string(),
+ None,
+ )),
],
false,
- ));
+ None,
+ )
+ .into();
return Ok(constraint);
}
}
diff --git a/crates/shirabe/src/installed_versions.rs b/crates/shirabe/src/installed_versions.rs
index 644cc8e..d52deac 100644
--- a/crates/shirabe/src/installed_versions.rs
+++ b/crates/shirabe/src/installed_versions.rs
@@ -171,7 +171,7 @@ impl InstalledVersions {
let constraint = parser.parse_constraints(constraint.unwrap_or(""))?;
let provided = parser.parse_constraints(&Self::get_version_ranges(package_name)?)?;
- Ok(provided.matches(&*constraint))
+ Ok(provided.matches(&constraint))
}
/// Returns a version constraint representing all the range(s) which are installed for a given package
diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs
index 3ccb65f..8b68a78 100644
--- a/crates/shirabe/src/installer.rs
+++ b/crates/shirabe/src/installer.rs
@@ -97,8 +97,8 @@ use crate::repository::RepositorySet;
use crate::repository::RootPackageRepository;
use crate::script::ScriptEvents;
use crate::util::Platform;
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
#[derive(Debug)]
pub struct Installer {
@@ -144,7 +144,7 @@ pub struct Installer {
pub(crate) suggested_packages_reporter: SuggestedPackagesReporter,
pub(crate) platform_requirement_filter: Box<dyn PlatformRequirementFilterInterface>,
pub(crate) additional_fixed_repository: Option<Box<dyn RepositoryInterface>>,
- pub(crate) temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>,
+ pub(crate) temporary_constraints: IndexMap<String, AnyConstraint>,
}
impl Installer {
@@ -1049,8 +1049,7 @@ impl Installer {
}
for (_key, link) in &root_requires {
if PlatformRepository::is_platform_package(link.get_target()) {
- request
- .require_name(link.get_target(), Some(link.get_constraint().clone_box()))?;
+ request.require_name(link.get_target(), Some(link.get_constraint().clone()))?;
}
}
@@ -1060,8 +1059,7 @@ impl Installer {
.get_platform_requirements(self.dev_mode)?
{
if !root_requires.contains_key(link.get_target()) {
- request
- .require_name(link.get_target(), Some(link.get_constraint().clone_box()))?;
+ request.require_name(link.get_target(), Some(link.get_constraint().clone()))?;
}
}
drop(root_requires);
@@ -1249,7 +1247,7 @@ impl Installer {
let minimum_stability: String;
let mut stability_flags: IndexMap<String, i64>;
- let requires: IndexMap<String, Box<dyn ConstraintInterface>>;
+ let requires: IndexMap<String, AnyConstraint>;
if for_update {
minimum_stability = self.package.get_minimum_stability().to_string();
stability_flags = self.package.get_stability_flags().clone();
@@ -1263,9 +1261,9 @@ impl Installer {
req_links.insert(k, v);
}
// Translate to constraint map for downstream uniform handling.
- let mut tmp: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut tmp: IndexMap<String, AnyConstraint> = IndexMap::new();
for (k, link) in req_links {
- tmp.insert(k, link.get_constraint().clone_box());
+ tmp.insert(k, link.get_constraint().clone());
}
requires = tmp;
} else {
@@ -1286,16 +1284,19 @@ impl Installer {
})
.unwrap_or_default();
- let mut tmp: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut tmp: IndexMap<String, AnyConstraint> = IndexMap::new();
for package in locked_repository.unwrap().get_packages() {
- let mut constraint = Constraint::new("=", package.get_version().to_string());
- constraint.set_pretty_string(Some(package.get_pretty_version().to_string()));
- tmp.insert(package.get_name().to_string(), Box::new(constraint));
+ let constraint = SimpleConstraint::new(
+ "=".to_string(),
+ package.get_version().to_string(),
+ Some(package.get_pretty_version().to_string()),
+ );
+ tmp.insert(package.get_name().to_string(), constraint.into());
}
requires = tmp;
}
- let mut root_requires: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut root_requires: IndexMap<String, AnyConstraint> = IndexMap::new();
for (req, mut constraint) in requires {
// skip platform requirements from the root package to avoid filtering out existing platform packages
if self.platform_requirement_filter.is_ignored(&req) {
@@ -1307,7 +1308,10 @@ impl Installer {
{
constraint = filter
.filter_constraint(&req, constraint, false)
- .unwrap_or_else(|_| Box::new(Constraint::new("=", String::new())));
+ .unwrap_or_else(|_| {
+ SimpleConstraint::new("=".to_string(), String::new().to_string(), None)
+ .into()
+ });
}
root_requires.insert(req, constraint);
}
@@ -1327,8 +1331,7 @@ impl Installer {
// TODO(phase-b): convert root_aliases (Vec<IndexMap<String, String>>) into Vec<RootAliasInput>
let root_aliases_input: Vec<crate::repository::RootAliasInput> = vec![];
let _ = root_aliases;
- // TODO(phase-b): temporary_constraints holds Box<dyn ConstraintInterface> which can't Clone
- let temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let temporary_constraints: IndexMap<String, AnyConstraint> = IndexMap::new();
let mut repository_set = RepositorySet::new(
&minimum_stability,
stability_flags,
@@ -1467,7 +1470,14 @@ impl Installer {
.get(package.get_name())
.unwrap()
.get_constraint()
- .matches(&Constraint::new("=", package.get_version().to_string()))
+ .matches(
+ &SimpleConstraint::new(
+ "=".to_string(),
+ package.get_version().to_string(),
+ None,
+ )
+ .into(),
+ )
{
// TODO(phase-b): fix_package needs owned Box<dyn BasePackage>
let _ = &package;
@@ -1510,10 +1520,14 @@ impl Installer {
{
request.require_name(
locked_package.get_name(),
- Some(Box::new(Constraint::new(
- "==",
- locked_package.get_version().to_string(),
- ))),
+ Some(
+ SimpleConstraint::new(
+ "==".to_string(),
+ locked_package.get_version().to_string(),
+ None,
+ )
+ .into(),
+ ),
)?;
}
}
@@ -1525,7 +1539,7 @@ impl Installer {
}
}
for (_key, link) in &links {
- request.require_name(link.get_target(), Some(link.get_constraint().clone_box()))?;
+ request.require_name(link.get_target(), Some(link.get_constraint().clone()))?;
}
}
Ok(())
@@ -1674,7 +1688,7 @@ impl Installer {
pub fn set_temporary_constraints(
&mut self,
- constraints: IndexMap<String, Box<dyn ConstraintInterface>>,
+ constraints: IndexMap<String, AnyConstraint>,
) -> &mut Self {
self.temporary_constraints = constraints;
diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs
index 0d687a1..e9b5dbf 100644
--- a/crates/shirabe/src/package/alias_package.rs
+++ b/crates/shirabe/src/package/alias_package.rs
@@ -3,7 +3,8 @@
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_php_shim::{PhpMixed, in_array};
-use shirabe_semver::constraint::Constraint;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::package::BasePackage;
use crate::package::Link;
@@ -177,18 +178,18 @@ impl AliasPackage {
for link in &links {
// link is self.version, but must be replacing also the replaced version
if link.get_pretty_constraint().unwrap_or("") == "self.version" {
- let mut constraint = Constraint::new("=", &self.version);
+ let constraint = SimpleConstraint::new(
+ "=".to_string(),
+ self.version.to_string(),
+ Some(pretty_version.clone()),
+ );
let new_link = Link::new(
link.get_source().to_string(),
link.get_target().to_string(),
- Box::new(constraint.clone()),
+ constraint.into(),
Some(link_type.to_string()),
Some(pretty_version.clone()),
);
- shirabe_semver::constraint::ConstraintInterface::set_pretty_string(
- &mut constraint,
- Some(pretty_version.clone()),
- );
new_links.push(new_link);
}
}
@@ -200,18 +201,18 @@ impl AliasPackage {
if link_type == Link::TYPE_REQUIRE {
self.has_self_version_requires = true;
}
- let mut constraint = Constraint::new("=", &self.version);
+ let constraint = SimpleConstraint::new(
+ "=".to_string(),
+ self.version.to_string(),
+ Some(pretty_version.clone()),
+ );
let new_link = Link::new(
links[index].get_source().to_string(),
links[index].get_target().to_string(),
- Box::new(constraint.clone()),
+ constraint.into(),
Some(link_type.to_string()),
Some(pretty_version.clone()),
);
- shirabe_semver::constraint::ConstraintInterface::set_pretty_string(
- &mut constraint,
- Some(pretty_version.clone()),
- );
links[index] = new_link;
}
}
diff --git a/crates/shirabe/src/package/link.rs b/crates/shirabe/src/package/link.rs
index 80a98c7..d606c63 100644
--- a/crates/shirabe/src/package/link.rs
+++ b/crates/shirabe/src/package/link.rs
@@ -1,14 +1,14 @@
//! ref: composer/src/Composer/Package/Link.php
use shirabe_php_shim::UnexpectedValueException;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use crate::package::PackageInterface;
pub struct Link {
pub(crate) source: String,
pub(crate) target: String,
- pub(crate) constraint: Box<dyn ConstraintInterface>,
+ pub(crate) constraint: AnyConstraint,
pub(crate) description: String,
pub(crate) pretty_constraint: Option<String>,
}
@@ -20,7 +20,7 @@ impl Clone for Link {
Self {
source: self.source.clone(),
target: self.target.clone(),
- constraint: self.constraint.clone_box(),
+ constraint: self.constraint.clone(),
description: self.description.clone(),
pretty_constraint: self.pretty_constraint.clone(),
}
@@ -63,7 +63,7 @@ impl Link {
pub fn new(
source: String,
target: String,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
description: Option<String>,
pretty_constraint: Option<String>,
) -> Self {
@@ -94,8 +94,8 @@ impl Link {
&self.target
}
- pub fn get_constraint(&self) -> &dyn ConstraintInterface {
- &*self.constraint
+ pub fn get_constraint(&self) -> &AnyConstraint {
+ &self.constraint
}
pub fn get_pretty_constraint(&self) -> anyhow::Result<&str> {
@@ -117,7 +117,7 @@ impl Link {
self.source,
self.description,
self.target,
- self.constraint.__to_string(),
+ self.constraint.to_string(),
)
}
diff --git a/crates/shirabe/src/package/loader/array_loader.rs b/crates/shirabe/src/package/loader/array_loader.rs
index ffbe465..87d6e35 100644
--- a/crates/shirabe/src/package/loader/array_loader.rs
+++ b/crates/shirabe/src/package/loader/array_loader.rs
@@ -764,12 +764,10 @@ impl ArrayLoader {
}
};
- // TODO(phase-b): Link::new expects Box<dyn ConstraintInterface>; we have Arc<dyn ConstraintInterface + Send + Sync>
- let _ = parsed_constraint;
Ok(Link::new(
source.to_string(),
target.to_string(),
- todo!("phase-b: convert Arc<dyn ConstraintInterface> to Box<dyn ConstraintInterface>"),
+ parsed_constraint,
Some(description.to_string()),
Some(pretty_constraint.to_string()),
))
diff --git a/crates/shirabe/src/package/loader/validating_array_loader.rs b/crates/shirabe/src/package/loader/validating_array_loader.rs
index 59fc266..a2dd5a7 100644
--- a/crates/shirabe/src/package/loader/validating_array_loader.rs
+++ b/crates/shirabe/src/package/loader/validating_array_loader.rs
@@ -11,9 +11,9 @@ use shirabe_php_shim::{
is_string, json_encode, parse_url_all, php_to_string, sprintf, str_replace, strcasecmp,
strtolower, strtotime, substr, trigger_error, trim, var_export,
};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchNoneConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use shirabe_semver::intervals::Intervals;
use crate::package::loader::InvalidPackageException;
@@ -877,7 +877,8 @@ impl ValidatingArrayLoader {
}
}
- let unbound_constraint = Constraint::new("=", "10000000-dev");
+ let unbound_constraint =
+ SimpleConstraint::new("=".to_string(), "10000000-dev".to_string(), None).into();
let link_types: Vec<&'static str> = SUPPORTED_LINK_TYPES.keys().copied().collect();
for link_type in link_types {
@@ -952,11 +953,14 @@ impl ValidatingArrayLoader {
} else if (self.flags & Self::CHECK_STRICT_CONSTRAINTS) != 0
&& link_type == "require"
&& link_constraint
- .as_any()
- .downcast_ref::<Constraint>()
+ .as_constraint()
.map_or(false, |c| ["==", "="].contains(&c.get_operator()))
- && Constraint::new(">=", "1.0.0.0-dev")
- .matches(link_constraint.as_ref())
+ && AnyConstraint::from(SimpleConstraint::new(
+ ">=".to_string(),
+ "1.0.0.0-dev".to_string(),
+ None,
+ ))
+ .matches(&link_constraint)
{
self.warnings.push(format!(
"{}.{} : exact version constraints ({}) should be avoided if the package follows semantic versioning",
@@ -964,8 +968,8 @@ impl ValidatingArrayLoader {
));
}
- let compacted = Intervals::compact_constraint(link_constraint.as_ref())?;
- if compacted.as_any().is::<MatchNoneConstraint>() {
+ let compacted = Intervals::compact_constraint(&link_constraint)?;
+ if compacted.is_match_none() {
self.warnings.push(format!(
"{}.{} : this version constraint cannot possibly match anything ({})",
link_type, package, constraint_str
diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs
index ecd96e3..9522e55 100644
--- a/crates/shirabe/src/package/locker.rs
+++ b/crates/shirabe/src/package/locker.rs
@@ -967,7 +967,7 @@ impl Locker {
.find_packages_with_replacers_and_providers(
&link.get_target(),
Some(FindPackageConstraint::Constraint(
- link.get_constraint().clone_box(),
+ link.get_constraint().clone(),
)),
)
.is_empty()
diff --git a/crates/shirabe/src/package/version/version_bumper.rs b/crates/shirabe/src/package/version/version_bumper.rs
index a9b5a67..8cc4b5d 100644
--- a/crates/shirabe/src/package/version/version_bumper.rs
+++ b/crates/shirabe/src/package/version/version_bumper.rs
@@ -8,7 +8,7 @@ use crate::util::Platform;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::intervals::Intervals;
#[derive(Debug)]
@@ -17,7 +17,7 @@ pub struct VersionBumper;
impl VersionBumper {
pub fn bump_requirement(
&self,
- constraint: &dyn ConstraintInterface,
+ constraint: &AnyConstraint,
package: &dyn PackageInterface,
) -> Result<String> {
let parser = VersionParser::new();
@@ -114,8 +114,8 @@ impl VersionBumper {
}
let new_constraint = parser.parse_constraints(&modified)?;
- if Intervals::is_subset_of(new_constraint.as_ref(), constraint)?
- && Intervals::is_subset_of(constraint, new_constraint.as_ref())?
+ if Intervals::is_subset_of(&new_constraint, constraint)?
+ && Intervals::is_subset_of(constraint, &new_constraint)?
{
return Ok(pretty_constraint);
}
diff --git a/crates/shirabe/src/package/version/version_parser.rs b/crates/shirabe/src/package/version/version_parser.rs
index 46a2356..1b588bc 100644
--- a/crates/shirabe/src/package/version/version_parser.rs
+++ b/crates/shirabe/src/package/version/version_parser.rs
@@ -1,16 +1,16 @@
//! ref: composer/src/Composer/Package/Version/VersionParser.php
use indexmap::IndexMap;
-use std::sync::{Arc, LazyLock, Mutex};
+use std::sync::{LazyLock, Mutex};
use shirabe_external_packages::composer::pcre::Preg;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::semver::Semver;
use shirabe_semver::version_parser::VersionParser as SemverVersionParser;
use crate::repository::PlatformRepository;
-static CONSTRAINTS: LazyLock<Mutex<IndexMap<String, Arc<dyn ConstraintInterface + Send + Sync>>>> =
+static CONSTRAINTS: LazyLock<Mutex<IndexMap<String, AnyConstraint>>> =
LazyLock::new(|| Mutex::new(IndexMap::new()));
#[derive(Debug, Clone)]
@@ -21,12 +21,19 @@ pub struct VersionParser {
impl VersionParser {
pub const DEFAULT_BRANCH_ALIAS: &'static str = "9999999-dev";
- pub fn parse_constraints(
- &self,
- constraints: &str,
- ) -> anyhow::Result<Box<dyn ConstraintInterface>> {
- // TODO(phase-b): re-introduce a memoization cache once trait objects are Send+Sync.
- self.inner.parse_constraints(constraints)
+ pub fn parse_constraints(&self, constraints: &str) -> anyhow::Result<AnyConstraint> {
+ {
+ let cache = CONSTRAINTS.lock().unwrap();
+ if let Some(cached) = cache.get(constraints) {
+ return Ok(cached.clone());
+ }
+ }
+ let parsed = self.inner.parse_constraints(constraints)?;
+ CONSTRAINTS
+ .lock()
+ .unwrap()
+ .insert(constraints.to_string(), parsed.clone());
+ Ok(parsed)
}
pub fn parse_name_version_pairs(
diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs
index 832f64c..3bd0191 100644
--- a/crates/shirabe/src/package/version/version_selector.rs
+++ b/crates/shirabe/src/package/version/version_selector.rs
@@ -8,8 +8,8 @@ use shirabe_external_packages::composer::pcre::Preg;
use shirabe_php_shim::{
PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, strtolower, version_compare,
};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::filter::platform_requirement_filter::IgnoreAllPlatformRequirementFilter;
use crate::filter::platform_requirement_filter::IgnoreListPlatformRequirementFilter;
@@ -29,7 +29,7 @@ use crate::repository::RepositorySet;
#[derive(Debug)]
pub struct VersionSelector {
repository_set: RepositorySet,
- platform_constraints: IndexMap<String, Vec<Box<dyn ConstraintInterface>>>,
+ platform_constraints: IndexMap<String, Vec<AnyConstraint>>,
parser: Option<VersionParser>,
}
@@ -38,16 +38,19 @@ impl VersionSelector {
repository_set: RepositorySet,
platform_repo: Option<&crate::repository::PlatformRepository>,
) -> anyhow::Result<Self> {
- let mut platform_constraints: IndexMap<String, Vec<Box<dyn ConstraintInterface>>> =
- IndexMap::new();
+ let mut platform_constraints: IndexMap<String, Vec<AnyConstraint>> = IndexMap::new();
if let Some(platform_repo) = platform_repo {
for package in <PlatformRepository as RepositoryInterface>::get_packages(platform_repo)
{
- let constraint = Constraint::new("==", package.get_version());
+ let constraint = SimpleConstraint::new(
+ "==".to_string(),
+ package.get_version().to_string(),
+ None,
+ );
platform_constraints
.entry(package.get_name().to_string())
.or_default()
- .push(Box::new(constraint));
+ .push(constraint.into());
}
}
Ok(Self {
@@ -90,7 +93,7 @@ impl VersionSelector {
};
let mut candidates = self.repository_set.find_packages(
&strtolower(package_name),
- constraint.as_ref().map(|c| c.clone_box()),
+ constraint.as_ref().map(|c| c.clone()),
repo_set_flags,
);
@@ -142,7 +145,7 @@ impl VersionSelector {
let reason;
if let Some(provided_constraints) = self.platform_constraints.get(name) {
for provided_constraint in provided_constraints {
- if link.get_constraint().matches(provided_constraint.as_ref()) {
+ if link.get_constraint().matches(provided_constraint) {
continue 'reqs;
}
let list_filter_opt = platform_requirement_filter
@@ -154,10 +157,10 @@ impl VersionSelector {
if list_filter.is_upper_bound_ignored(name) {
let filtered_constraint = list_filter.filter_constraint(
name,
- link.get_constraint().clone_box(),
+ link.get_constraint().clone(),
false,
)?;
- if filtered_constraint.matches(provided_constraint.as_ref()) {
+ if filtered_constraint.matches(provided_constraint) {
continue 'reqs;
}
}
diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs
index 26e6296..77ac577 100644
--- a/crates/shirabe/src/plugin/plugin_manager.rs
+++ b/crates/shirabe/src/plugin/plugin_manager.rs
@@ -13,7 +13,8 @@ use shirabe_php_shim::{
is_array, is_string, ksort, preg_quote, str_replace, strrpos, strtr, substr, trigger_error,
trim, var_export, var_export_str, version_compare,
};
-use shirabe_semver::constraint::Constraint;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::composer::PartialComposerHandle;
use crate::composer::{ComposerHandle, ComposerWeakHandle};
@@ -227,9 +228,7 @@ impl PluginManager {
if package.get_type() == "composer-plugin" {
let requires_map = package.get_requires();
- let mut requires_composer: Option<
- &dyn shirabe_semver::constraint::ConstraintInterface,
- > = None;
+ let mut requires_composer: Option<&shirabe_semver::constraint::AnyConstraint> = None;
for (_k, link) in &requires_map {
if "composer-plugin-api" == link.get_target() {
requires_composer = Some(link.get_constraint());
@@ -248,15 +247,17 @@ impl PluginManager {
};
let current_plugin_api_version = self.get_plugin_api_version();
- let current_plugin_api_constraint = Constraint::new(
- "==",
+ let current_plugin_api_constraint = SimpleConstraint::new(
+ "==".to_string(),
self.version_parser
- .normalize(&current_plugin_api_version, None)?,
+ .normalize(&current_plugin_api_version, None)?
+ .to_string(),
+ None,
);
if requires_composer.get_pretty_string() == self.get_plugin_api_version() {
self.io.write_error(&format!("<warning>The \"{}\" plugin requires composer-plugin-api {}, this *WILL* break in the future and it should be fixed ASAP (require ^{} instead for example).</warning>", package.get_name(), self.get_plugin_api_version(), self.get_plugin_api_version()));
- } else if !requires_composer.matches(&current_plugin_api_constraint) {
+ } else if !requires_composer.matches(&current_plugin_api_constraint.into()) {
self.io.write_error(&format!("<warning>The \"{}\" plugin {}was skipped because it requires a Plugin API version (\"{}\") that does not match your Composer installation (\"{}\"). You may need to run composer update with the \"--no-plugins\" option.</warning>",
package.get_name(),
if is_global_plugin || self.running_in_global_dir { "(installed globally) " } else { "" },
diff --git a/crates/shirabe/src/repository/advisory_provider_interface.rs b/crates/shirabe/src/repository/advisory_provider_interface.rs
index 4c08a63..0de9c42 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 f8d2e0c..fe45849 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 4bd5442..9752bc0 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 b3ac1dd..6671895 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 8a0e6f6..a3cb18b 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 fd273b9..b089df6 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 db1428a..5c6fecf 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 3163ed2..5c9e0d7 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 295d982..57abe56 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 6e8186c..93c7e31 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 8494e25..0b3ccb1 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 d18951b..4bd1f3e 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 10e3e37..e85312a 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 84b2424..84159d4 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 6213291..1487f3e 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 05dd329..1ae7e40 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!(
diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs
index b1cf921..77d35b1 100644
--- a/crates/shirabe/src/util/http_downloader.rs
+++ b/crates/shirabe/src/util/http_downloader.rs
@@ -10,7 +10,8 @@ use shirabe_php_shim::{
extension_loaded, file_get_contents, function_exists, implode, is_numeric, max, min,
rawurldecode, stream_context_create, stripos, strpos, substr, ucfirst,
};
-use shirabe_semver::constraint::Constraint;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::composer;
use crate::composer::ComposerHandle;
@@ -715,11 +716,14 @@ impl HttpDownloader {
let version_parser: VersionParser = todo!("VersionParser::new()");
let constraint = version_parser
.parse_constraints(versions_value.as_string().unwrap_or(""))?;
- let composer_constraint = Constraint::new(
- "==",
- &version_parser.normalize(&composer::get_version(), None)?,
+ let composer_constraint = SimpleConstraint::new(
+ "==".to_string(),
+ version_parser
+ .normalize(&composer::get_version(), None)?
+ .to_string(),
+ None,
);
- if !constraint.matches(&composer_constraint) {
+ if !constraint.matches(&composer_constraint.into()) {
continue;
}
}
@@ -753,11 +757,14 @@ impl HttpDownloader {
.and_then(|v| v.as_string())
.unwrap_or(""),
)?;
- let composer_constraint = Constraint::new(
- "==",
- &version_parser.normalize(&composer::get_version(), None)?,
+ let composer_constraint = SimpleConstraint::new(
+ "==".to_string(),
+ version_parser
+ .normalize(&composer::get_version(), None)?
+ .to_string(),
+ None,
);
- if !constraint.matches(&composer_constraint) {
+ if !constraint.matches(&composer_constraint.into()) {
continue;
}