diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-15 00:57:02 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-15 19:51:17 +0900 |
| commit | a9d321f731b13b6cdbd3f8069d6bd60558038edf (patch) | |
| tree | 0cf03a0ef0618d388b5775cc6572e012f6b10d18 /crates/shirabe/src | |
| parent | 2523443bf77002d1d1fcfaae8be140702d2a75d0 (diff) | |
| download | php-shirabe-a9d321f731b13b6cdbd3f8069d6bd60558038edf.tar.gz php-shirabe-a9d321f731b13b6cdbd3f8069d6bd60558038edf.tar.zst php-shirabe-a9d321f731b13b6cdbd3f8069d6bd60558038edf.zip | |
feat(port): port RuleWatchNode.php
Diffstat (limited to 'crates/shirabe/src')
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; + } + } +} |
