aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-semver/src/constraint/constraint.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-semver/src/constraint/constraint.rs')
-rw-r--r--crates/shirabe-semver/src/constraint/constraint.rs409
1 files changed, 0 insertions, 409 deletions
diff --git a/crates/shirabe-semver/src/constraint/constraint.rs b/crates/shirabe-semver/src/constraint/constraint.rs
deleted file mode 100644
index 3ac633d..0000000
--- a/crates/shirabe-semver/src/constraint/constraint.rs
+++ /dev/null
@@ -1,409 +0,0 @@
-//! 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 {
- 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 {
- pub const OP_EQ: i64 = 0;
- pub const OP_LT: i64 = 1;
- pub const OP_LE: i64 = 2;
- pub const OP_GT: i64 = 3;
- pub const OP_GE: i64 = 4;
- pub const OP_NE: i64 = 5;
-
- pub const STR_OP_EQ: &'static str = "==";
- pub const STR_OP_EQ_ALT: &'static str = "=";
- pub const STR_OP_LT: &'static str = "<";
- pub const STR_OP_LE: &'static str = "<=";
- pub const STR_OP_GT: &'static str = ">";
- pub const STR_OP_GE: &'static str = ">=";
- pub const STR_OP_NE: &'static str = "!=";
- pub const STR_OP_NE_ALT: &'static str = "<>";
-
- fn trans_op_str(op: &str) -> Option<i64> {
- match op {
- "=" => Some(Self::OP_EQ),
- "==" => Some(Self::OP_EQ),
- "<" => Some(Self::OP_LT),
- "<=" => Some(Self::OP_LE),
- ">" => Some(Self::OP_GT),
- ">=" => Some(Self::OP_GE),
- "<>" => Some(Self::OP_NE),
- "!=" => Some(Self::OP_NE),
- _ => None,
- }
- }
-
- fn trans_op_int(op: i64) -> &'static str {
- match op {
- Self::OP_EQ => "==",
- Self::OP_LT => "<",
- Self::OP_LE => "<=",
- Self::OP_GT => ">",
- Self::OP_GE => ">=",
- Self::OP_NE => "!=",
- _ => panic!("unknown operator: {}", op),
- }
- }
-
- pub fn new(operator: impl Into<String>, version: impl Into<String>) -> Self {
- let operator: String = operator.into();
- 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.
- panic!(
- "Invalid operator \"{}\" given, expected one of: {}",
- operator,
- Self::get_supported_operators().join(", ")
- )
- });
-
- Self {
- operator: op_int,
- version: version.into(),
- pretty_string: None,
- lower_bound: Mutex::new(None),
- upper_bound: Mutex::new(None),
- }
- }
-
- pub fn get_version(&self) -> &str {
- &self.version
- }
-
- pub fn get_operator(&self) -> &'static str {
- Self::trans_op_int(self.operator)
- }
-
- pub fn get_supported_operators() -> Vec<&'static str> {
- vec!["=", "==", "<", "<=", ">", ">=", "<>", "!="]
- }
-
- pub fn get_operator_constant(operator: &str) -> i64 {
- Self::trans_op_str(operator).expect("valid operator")
- }
-
- pub fn version_compare(
- &self,
- a: &str,
- b: &str,
- operator: &str,
- compare_branches: bool,
- ) -> anyhow::Result<bool> {
- if Self::trans_op_str(operator).is_none() {
- bail!(
- "Invalid operator \"{}\" given, expected one of: {}",
- operator,
- Self::get_supported_operators().join(", ")
- );
- }
-
- let a_is_branch = a.starts_with("dev-");
- let b_is_branch = b.starts_with("dev-");
-
- if operator == "!=" && (a_is_branch || b_is_branch) {
- return Ok(a != b);
- }
-
- if a_is_branch && b_is_branch {
- return Ok(operator == "==" && a == b);
- }
-
- if !compare_branches && (a_is_branch || b_is_branch) {
- return Ok(false);
- }
-
- Ok(php::version_compare(a, b, operator))
- }
-
- pub fn compile_constraint(&self, other_operator: i64) -> String {
- if self.version.starts_with("dev-") {
- if Self::OP_EQ == self.operator {
- if Self::OP_EQ == other_operator {
- return format!("$b && $v === {}", php::var_export_str(&self.version, true));
- }
- if Self::OP_NE == other_operator {
- return format!("!$b || $v !== {}", php::var_export_str(&self.version, true));
- }
- return "false".to_string();
- }
-
- if Self::OP_NE == self.operator {
- if Self::OP_EQ == other_operator {
- return format!("!$b || $v !== {}", php::var_export_str(&self.version, true));
- }
- if Self::OP_NE == other_operator {
- return "true".to_string();
- }
- return "!$b".to_string();
- }
-
- return "false".to_string();
- }
-
- if Self::OP_EQ == self.operator {
- if Self::OP_EQ == other_operator {
- return format!(
- "\\version_compare($v, {}, '==')",
- php::var_export_str(&self.version, true)
- );
- }
- if Self::OP_NE == other_operator {
- return format!(
- "$b || \\version_compare($v, {}, '!=')",
- php::var_export_str(&self.version, true)
- );
- }
- return format!(
- "!$b && \\version_compare({}, $v, '{}')",
- php::var_export_str(&self.version, true),
- Self::trans_op_int(other_operator)
- );
- }
-
- if Self::OP_NE == self.operator {
- if Self::OP_EQ == other_operator {
- return format!(
- "$b || (!$b && \\version_compare($v, {}, '!='))",
- php::var_export_str(&self.version, true)
- );
- }
- if Self::OP_NE == other_operator {
- return "true".to_string();
- }
- return "!$b".to_string();
- }
-
- if Self::OP_LT == self.operator || Self::OP_LE == self.operator {
- if Self::OP_LT == other_operator || Self::OP_LE == other_operator {
- return "!$b".to_string();
- }
- } else if Self::OP_GT == other_operator || Self::OP_GE == other_operator {
- return "!$b".to_string();
- }
-
- if Self::OP_NE == other_operator {
- return "true".to_string();
- }
-
- let code_comparison = format!(
- "\\version_compare($v, {}, '{}')",
- php::var_export_str(&self.version, true),
- Self::trans_op_int(self.operator)
- );
-
- if self.operator == Self::OP_LE && other_operator == Self::OP_GT {
- return format!(
- "!$b && \\version_compare($v, {}, '!=') && {}",
- php::var_export_str(&self.version, true),
- code_comparison
- );
- }
-
- if self.operator == Self::OP_GE && other_operator == Self::OP_LT {
- return format!(
- "!$b && \\version_compare($v, {}, '!=') && {}",
- php::var_export_str(&self.version, true),
- code_comparison
- );
- }
-
- format!("!$b && {}", code_comparison)
- }
-
- pub fn match_specific(&self, provider: &Constraint, 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('=', "");
-
- let is_equal_op = Self::OP_EQ == self.operator;
- let is_non_equal_op = Self::OP_NE == self.operator;
- let is_provider_equal_op = Self::OP_EQ == provider.operator;
- let is_provider_non_equal_op = Self::OP_NE == provider.operator;
-
- if is_non_equal_op || is_provider_non_equal_op {
- if is_non_equal_op
- && !is_provider_non_equal_op
- && !is_provider_equal_op
- && provider.version.starts_with("dev-")
- {
- return false;
- }
-
- if is_provider_non_equal_op
- && !is_non_equal_op
- && !is_equal_op
- && self.version.starts_with("dev-")
- {
- return false;
- }
-
- if !is_equal_op && !is_provider_equal_op {
- return true;
- }
- return self
- .version_compare(&provider.version, &self.version, "!=", compare_branches)
- .expect("valid operator");
- }
-
- if self.operator != Self::OP_EQ && no_equal_op == provider_no_equal_op {
- return !(self.version.starts_with("dev-") || provider.version.starts_with("dev-"));
- }
-
- let (version1, version2, operator) = if is_equal_op {
- (&self.version, &provider.version, provider.operator)
- } else {
- (&provider.version, &self.version, self.operator)
- };
-
- if self
- .version_compare(
- version1,
- version2,
- Self::trans_op_int(operator),
- compare_branches,
- )
- .expect("valid operator")
- {
- return !(Self::trans_op_int(provider.operator) == provider_no_equal_op
- && Self::trans_op_int(self.operator) != no_equal_op
- && php::version_compare(&provider.version, &self.version, "=="));
- }
-
- false
- }
-
- fn extract_bounds(&self) {
- if self.lower_bound.lock().unwrap().is_some() {
- return;
- }
-
- if self.version.starts_with("dev-") {
- *self.lower_bound.lock().unwrap() = Some(Bound::zero());
- *self.upper_bound.lock().unwrap() = Some(Bound::positive_infinity());
- return;
- }
-
- let (lower, upper) = match self.operator {
- Self::OP_EQ => (
- Bound::new(self.version.clone(), true),
- Bound::new(self.version.clone(), true),
- ),
- Self::OP_LT => (Bound::zero(), Bound::new(self.version.clone(), false)),
- Self::OP_LE => (Bound::zero(), Bound::new(self.version.clone(), true)),
- Self::OP_GT => (
- Bound::new(self.version.clone(), false),
- Bound::positive_infinity(),
- ),
- Self::OP_GE => (
- Bound::new(self.version.clone(), true),
- Bound::positive_infinity(),
- ),
- 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 {
- 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 {
- if let Some(ref s) = self.pretty_string
- && !s.is_empty()
- {
- return s.clone();
- }
- self.__to_string()
- }
-
- fn __to_string(&self) -> String {
- format!("{} {}", Self::trans_op_int(self.operator), self.version)
- }
-
- 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
- }
-}
-
-impl std::fmt::Display for Constraint {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- use crate::constraint::ConstraintInterface;
- write!(f, "{}", ConstraintInterface::__to_string(self))
- }
-}