aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/dependency_resolver
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-15 00:43:57 +0900
committernsfisis <nsfisis@gmail.com>2026-05-15 02:37:37 +0900
commit36e367ffe00328c8d6271c8e218186d7a286bfa6 (patch)
treeb646924ea0a81ec7cf6ae2d37a0b39beb02ce4dd /crates/shirabe/src/dependency_resolver
parent5198120875a89cb9ce45056dab20b107e2b4efd2 (diff)
downloadphp-shirabe-36e367ffe00328c8d6271c8e218186d7a286bfa6.tar.gz
php-shirabe-36e367ffe00328c8d6271c8e218186d7a286bfa6.tar.zst
php-shirabe-36e367ffe00328c8d6271c8e218186d7a286bfa6.zip
feat(port): port RuleSetIterator.php
Diffstat (limited to 'crates/shirabe/src/dependency_resolver')
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_iterator.rs93
1 files changed, 93 insertions, 0 deletions
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs b/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs
index 6012876..e2b67f4 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs
@@ -1 +1,94 @@
//! ref: composer/src/Composer/DependencyResolver/RuleSetIterator.php
+
+use indexmap::IndexMap;
+use crate::dependency_resolver::rule::Rule;
+
+/// Implements PHP \Iterator over a grouped rule set.
+#[derive(Debug)]
+pub struct RuleSetIterator {
+ pub(crate) rules: IndexMap<i64, Vec<Rule>>,
+ pub(crate) types: Vec<i64>,
+ pub(crate) current_offset: i64,
+ pub(crate) current_type: i64,
+ pub(crate) current_type_offset: i64,
+}
+
+impl RuleSetIterator {
+ pub fn new(rules: IndexMap<i64, Vec<Rule>>) -> Self {
+ let mut types: Vec<i64> = rules.keys().copied().collect();
+ types.sort();
+ let mut iter = Self {
+ rules,
+ types,
+ current_offset: 0,
+ current_type: -1,
+ current_type_offset: 0,
+ };
+ iter.rewind();
+ iter
+ }
+
+ pub fn current(&self) -> &Rule {
+ &self.rules[&self.current_type][self.current_offset as usize]
+ }
+
+ pub fn key(&self) -> i64 {
+ self.current_type
+ }
+
+ pub fn next(&mut self) {
+ self.current_offset += 1;
+
+ if !self.rules.contains_key(&self.current_type) {
+ return;
+ }
+
+ if self.current_offset >= self.rules[&self.current_type].len() as i64 {
+ self.current_offset = 0;
+
+ loop {
+ self.current_type_offset += 1;
+
+ if self.types.get(self.current_type_offset as usize).is_none() {
+ self.current_type = -1;
+ break;
+ }
+
+ self.current_type = self.types[self.current_type_offset as usize];
+
+ if self.rules[&self.current_type].len() != 0 {
+ break;
+ }
+ }
+ }
+ }
+
+ pub fn rewind(&mut self) {
+ self.current_offset = 0;
+ self.current_type_offset = -1;
+ self.current_type = -1;
+
+ loop {
+ self.current_type_offset += 1;
+
+ if self.types.get(self.current_type_offset as usize).is_none() {
+ self.current_type = -1;
+ break;
+ }
+
+ self.current_type = self.types[self.current_type_offset as usize];
+
+ if self.rules[&self.current_type].len() != 0 {
+ break;
+ }
+ }
+ }
+
+ pub fn valid(&self) -> bool {
+ if let Some(rules) = self.rules.get(&self.current_type) {
+ rules.get(self.current_offset as usize).is_some()
+ } else {
+ false
+ }
+ }
+}