aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-17 04:56:37 +0900
committernsfisis <nsfisis@gmail.com>2026-05-17 04:57:23 +0900
commit8fb6de392bbac104c07a5cdbac12a4fd25ab1127 (patch)
tree9cbe66e913ae2166b1f976ae5a2a1e8a06492e97
parent90b3be462bd2f91ef366df06c2b5bbae2821a394 (diff)
downloadphp-shirabe-8fb6de392bbac104c07a5cdbac12a4fd25ab1127.tar.gz
php-shirabe-8fb6de392bbac104c07a5cdbac12a4fd25ab1127.tar.zst
php-shirabe-8fb6de392bbac104c07a5cdbac12a4fd25ab1127.zip
fix(semver): resolve shirabe-semver compile errors
- Replace RefCell with Mutex in Constraint for thread safety - Add clone_box() to ConstraintInterface for cloning trait objects - Propagate Result from Constraint::new() and unwrap at call sites - Fix VersionParser instantiation (unit struct, not fn) - Add indexmap dependency to shirabe-semver
-rw-r--r--Cargo.lock1
-rw-r--r--crates/shirabe-semver/Cargo.toml1
-rw-r--r--crates/shirabe-semver/src/comparator.rs4
-rw-r--r--crates/shirabe-semver/src/compiling_matcher.rs2
-rw-r--r--crates/shirabe-semver/src/constraint/constraint.rs44
-rw-r--r--crates/shirabe-semver/src/constraint/constraint_interface.rs2
-rw-r--r--crates/shirabe-semver/src/constraint/match_all_constraint.rs6
-rw-r--r--crates/shirabe-semver/src/constraint/match_none_constraint.rs6
-rw-r--r--crates/shirabe-semver/src/constraint/multi_constraint.rs15
-rw-r--r--crates/shirabe-semver/src/interval.rs7
-rw-r--r--crates/shirabe-semver/src/semver.rs11
11 files changed, 73 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b275c43..bd3ea0e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -931,6 +931,7 @@ name = "shirabe-semver"
version = "0.0.1"
dependencies = [
"anyhow",
+ "indexmap",
"shirabe-php-shim",
]
diff --git a/crates/shirabe-semver/Cargo.toml b/crates/shirabe-semver/Cargo.toml
index ca2875e..30ad164 100644
--- a/crates/shirabe-semver/Cargo.toml
+++ b/crates/shirabe-semver/Cargo.toml
@@ -6,3 +6,4 @@ edition.workspace = true
[dependencies]
shirabe-php-shim.workspace = true
anyhow.workspace = true
+indexmap.workspace = true
diff --git a/crates/shirabe-semver/src/comparator.rs b/crates/shirabe-semver/src/comparator.rs
index 575a656..0ae6d94 100644
--- a/crates/shirabe-semver/src/comparator.rs
+++ b/crates/shirabe-semver/src/comparator.rs
@@ -30,7 +30,7 @@ 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 = Constraint::new(operator, version2).unwrap();
+ constraint.match_specific(&Constraint::new("==".to_string(), version1).unwrap(), true)
}
}
diff --git a/crates/shirabe-semver/src/compiling_matcher.rs b/crates/shirabe-semver/src/compiling_matcher.rs
index f6a3689..942abe5 100644
--- a/crates/shirabe-semver/src/compiling_matcher.rs
+++ b/crates/shirabe-semver/src/compiling_matcher.rs
@@ -56,7 +56,7 @@ 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(&Constraint::new(trans_op.to_string(), version).unwrap());
Self::result_cache()
.lock()
diff --git a/crates/shirabe-semver/src/constraint/constraint.rs b/crates/shirabe-semver/src/constraint/constraint.rs
index b0c937c..8db322d 100644
--- a/crates/shirabe-semver/src/constraint/constraint.rs
+++ b/crates/shirabe-semver/src/constraint/constraint.rs
@@ -1,6 +1,6 @@
//! ref: composer/vendor/composer/semver/src/Constraint/Constraint.php
-use std::cell::RefCell;
+use std::sync::Mutex;
use anyhow::bail;
use shirabe_php_shim as php;
@@ -8,13 +8,13 @@ use shirabe_php_shim as php;
use crate::constraint::bound::Bound;
use crate::constraint::constraint_interface::ConstraintInterface;
-#[derive(Debug, Clone)]
+#[derive(Debug)]
pub struct Constraint {
pub(crate) operator: i64,
pub(crate) version: String,
pub(crate) pretty_string: Option<String>,
- pub(crate) lower_bound: RefCell<Option<Bound>>,
- pub(crate) upper_bound: RefCell<Option<Bound>>,
+ pub(crate) lower_bound: Mutex<Option<Bound>>,
+ pub(crate) upper_bound: Mutex<Option<Bound>>,
}
impl Constraint {
@@ -73,8 +73,8 @@ impl Constraint {
operator: op_int,
version,
pretty_string: None,
- lower_bound: RefCell::new(None),
- upper_bound: RefCell::new(None),
+ lower_bound: Mutex::new(None),
+ upper_bound: Mutex::new(None),
})
}
@@ -284,13 +284,13 @@ impl Constraint {
}
fn extract_bounds(&self) {
- if self.lower_bound.borrow().is_some() {
+ if self.lower_bound.lock().unwrap().is_some() {
return;
}
if self.version.starts_with("dev-") {
- *self.lower_bound.borrow_mut() = Some(Bound::zero());
- *self.upper_bound.borrow_mut() = Some(Bound::positive_infinity());
+ *self.lower_bound.lock().unwrap() = Some(Bound::zero());
+ *self.upper_bound.lock().unwrap() = Some(Bound::positive_infinity());
return;
}
@@ -313,8 +313,20 @@ impl Constraint {
_ => panic!("unknown operator: {}", self.operator),
};
- *self.lower_bound.borrow_mut() = Some(lower);
- *self.upper_bound.borrow_mut() = Some(upper);
+ *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()),
+ }
}
}
@@ -350,7 +362,8 @@ impl ConstraintInterface for Constraint {
fn get_lower_bound(&self) -> Bound {
self.extract_bounds();
self.lower_bound
- .borrow()
+ .lock()
+ .unwrap()
.clone()
.expect("extract_bounds should have set lower_bound")
}
@@ -358,11 +371,16 @@ impl ConstraintInterface for Constraint {
fn get_upper_bound(&self) -> Bound {
self.extract_bounds();
self.upper_bound
- .borrow()
+ .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
}
diff --git a/crates/shirabe-semver/src/constraint/constraint_interface.rs b/crates/shirabe-semver/src/constraint/constraint_interface.rs
index 980a23a..f8879b3 100644
--- a/crates/shirabe-semver/src/constraint/constraint_interface.rs
+++ b/crates/shirabe-semver/src/constraint/constraint_interface.rs
@@ -22,5 +22,7 @@ pub trait ConstraintInterface {
false
}
+ 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 4d7b988..b6b2445 100644
--- a/crates/shirabe-semver/src/constraint/match_all_constraint.rs
+++ b/crates/shirabe-semver/src/constraint/match_all_constraint.rs
@@ -34,6 +34,12 @@ impl ConstraintInterface for MatchAllConstraint {
"*".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
}
diff --git a/crates/shirabe-semver/src/constraint/match_none_constraint.rs b/crates/shirabe-semver/src/constraint/match_none_constraint.rs
index 4add794..17a45bb 100644
--- a/crates/shirabe-semver/src/constraint/match_none_constraint.rs
+++ b/crates/shirabe-semver/src/constraint/match_none_constraint.rs
@@ -34,6 +34,12 @@ impl ConstraintInterface for MatchNoneConstraint {
"[]".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
}
diff --git a/crates/shirabe-semver/src/constraint/multi_constraint.rs b/crates/shirabe-semver/src/constraint/multi_constraint.rs
index 86afa8d..29d6f5e 100644
--- a/crates/shirabe-semver/src/constraint/multi_constraint.rs
+++ b/crates/shirabe-semver/src/constraint/multi_constraint.rs
@@ -166,8 +166,8 @@ impl MultiConstraint {
Some(Box::new(
MultiConstraint::new(
vec![
- l_mc.constraints[0].clone(),
- r_mc.constraints[1].clone(),
+ l_mc.constraints[0].clone_box(),
+ r_mc.constraints[1].clone_box(),
],
true,
)
@@ -311,6 +311,17 @@ impl ConstraintInterface for MultiConstraint {
!self.conjunctive
}
+ 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()),
+ })
+ }
+
fn as_any(&self) -> &dyn std::any::Any {
self
}
diff --git a/crates/shirabe-semver/src/interval.rs b/crates/shirabe-semver/src/interval.rs
index 237ad0b..cf4f481 100644
--- a/crates/shirabe-semver/src/interval.rs
+++ b/crates/shirabe-semver/src/interval.rs
@@ -31,13 +31,14 @@ impl Interval {
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()))
+ ZERO.get_or_init(|| Constraint::new(">=".to_string(), "0.0.0.0-dev".to_string()).unwrap())
}
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)))
+ POSITIVE_INFINITY.get_or_init(|| {
+ Constraint::new("<".to_string(), format!("{}.0.0.0", i64::MAX)).unwrap()
+ })
}
pub fn any() -> Self {
diff --git a/crates/shirabe-semver/src/semver.rs b/crates/shirabe-semver/src/semver.rs
index 8fecf27..0aff3d7 100644
--- a/crates/shirabe-semver/src/semver.rs
+++ b/crates/shirabe-semver/src/semver.rs
@@ -14,13 +14,14 @@ impl Semver {
fn version_parser() -> &'static VersionParser {
static VERSION_PARSER: OnceLock<VersionParser> = OnceLock::new();
- VERSION_PARSER.get_or_init(VersionParser::new)
+ VERSION_PARSER.get_or_init(|| VersionParser)
}
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)?);
- let parsed_constraints = version_parser.parse_constraints(constraints)?;
+ let provider =
+ Constraint::new("==".to_string(), version_parser.normalize(&version, None)?)?;
+ let parsed_constraints = version_parser.parse_constraints(&constraints)?;
Ok(parsed_constraints.matches(&provider))
}
@@ -49,9 +50,9 @@ impl Semver {
.iter()
.enumerate()
.map(|(key, version)| -> anyhow::Result<(String, usize)> {
- let normalized_version = version_parser.normalize(version.clone())?;
+ let normalized_version = version_parser.normalize(version, None)?;
let normalized_version =
- version_parser.normalize_default_branch(normalized_version);
+ version_parser.normalize_default_branch(&normalized_version);
Ok((normalized_version, key))
})
.collect::<anyhow::Result<Vec<_>>>()?;