aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe')
-rw-r--r--crates/shirabe/src/dependency_resolver/generic_rule.rs1
-rw-r--r--crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs4
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_watch_node.rs70
3 files changed, 75 insertions, 0 deletions
diff --git a/crates/shirabe/src/dependency_resolver/generic_rule.rs b/crates/shirabe/src/dependency_resolver/generic_rule.rs
index 8e294c1..520d483 100644
--- a/crates/shirabe/src/dependency_resolver/generic_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/generic_rule.rs
@@ -67,6 +67,7 @@ impl GenericRule {
pub trait RuleLiterals {
fn get_literals(&self) -> &Vec<i64>;
+ fn is_multi_conflict_rule(&self) -> bool { false }
}
impl RuleLiterals for GenericRule {
diff --git a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
index fc07321..172b6f4 100644
--- a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
@@ -97,4 +97,8 @@ impl RuleLiterals for MultiConflictRule {
fn get_literals(&self) -> &Vec<i64> {
&self.literals
}
+
+ fn is_multi_conflict_rule(&self) -> bool {
+ true
+ }
}
diff --git a/crates/shirabe/src/dependency_resolver/rule_watch_node.rs b/crates/shirabe/src/dependency_resolver/rule_watch_node.rs
index c7b50df..4161268 100644
--- a/crates/shirabe/src/dependency_resolver/rule_watch_node.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_watch_node.rs
@@ -1 +1,71 @@
//! ref: composer/src/Composer/DependencyResolver/RuleWatchNode.php
+
+use crate::dependency_resolver::decisions::Decisions;
+use crate::dependency_resolver::generic_rule::RuleLiterals;
+
+pub struct RuleWatchNode {
+ pub watch1: i64,
+ pub watch2: i64,
+ pub(crate) rule: Box<dyn RuleLiterals>,
+}
+
+impl std::fmt::Debug for RuleWatchNode {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("RuleWatchNode")
+ .field("watch1", &self.watch1)
+ .field("watch2", &self.watch2)
+ .finish()
+ }
+}
+
+impl RuleWatchNode {
+ pub fn new(rule: Box<dyn RuleLiterals>) -> Self {
+ let literals = rule.get_literals();
+ let literal_count = literals.len();
+ let watch1 = if literal_count > 0 { literals[0] } else { 0 };
+ let watch2 = if literal_count > 1 { literals[1] } else { 0 };
+
+ Self { watch1, watch2, rule }
+ }
+
+ pub fn watch2_on_highest(&mut self, decisions: &Decisions) {
+ let literals = self.rule.get_literals();
+
+ // if there are only 2 elements, both are being watched anyway
+ if literals.len() < 3 || self.rule.is_multi_conflict_rule() {
+ return;
+ }
+
+ let literals: Vec<i64> = literals.clone();
+ let mut watch_level: i64 = 0;
+
+ for literal in &literals {
+ let level = decisions.decision_level(*literal);
+
+ if level > watch_level {
+ self.watch2 = *literal;
+ watch_level = level;
+ }
+ }
+ }
+
+ pub fn get_rule(&self) -> &dyn RuleLiterals {
+ self.rule.as_ref()
+ }
+
+ pub fn get_other_watch(&self, literal: i64) -> i64 {
+ if self.watch1 == literal {
+ return self.watch2;
+ }
+
+ self.watch1
+ }
+
+ pub fn move_watch(&mut self, from: i64, to: i64) {
+ if self.watch1 == from {
+ self.watch1 = to;
+ } else {
+ self.watch2 = to;
+ }
+ }
+}