diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-15 00:43:57 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-15 02:37:37 +0900 |
| commit | 36e367ffe00328c8d6271c8e218186d7a286bfa6 (patch) | |
| tree | b646924ea0a81ec7cf6ae2d37a0b39beb02ce4dd /crates/shirabe/src/dependency_resolver | |
| parent | 5198120875a89cb9ce45056dab20b107e2b4efd2 (diff) | |
| download | php-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.rs | 93 |
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 + } + } +} |
