aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-semver/src/constraint/any_constraint.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-semver/src/constraint/any_constraint.rs')
-rw-r--r--crates/shirabe-semver/src/constraint/any_constraint.rs169
1 files changed, 169 insertions, 0 deletions
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),
+ }
+ }
+}