diff --git a/src/Selector/Modifier/AtMostModifier.php b/src/Selector/Modifier/AtMostModifier.php new file mode 100644 index 00000000..e6e7a7ef --- /dev/null +++ b/src/Selector/Modifier/AtMostModifier.php @@ -0,0 +1,39 @@ +max = $max; + $this->selectors = array_values($selector); + } + + public function matches(ClassReflection $classReflection): bool + { + $matches = 0; + + foreach ($this->selectors as $selector) { + if ($selector->matches($classReflection)) { + ++$matches; + } + } + + return $matches <= $this->max; + } + + public function getName(): string + { + return 'at-most-'.$this->max.'-of: '.implode( + ', ', + array_map(static fn (SelectorInterface $selector) => $selector->getName(), $this->selectors), + ); + } +} diff --git a/src/Selector/Selector.php b/src/Selector/Selector.php index e89e8a29..cda00bcf 100644 --- a/src/Selector/Selector.php +++ b/src/Selector/Selector.php @@ -3,6 +3,7 @@ namespace PHPat\Selector; use PHPat\Selector\Modifier\AndModifier; +use PHPat\Selector\Modifier\AtMostModifier; use PHPat\Selector\Modifier\NotModifier; final class Selector extends SelectorPrimitive @@ -16,4 +17,9 @@ public static function NOT(SelectorInterface $selector): NotModifier { return new NotModifier($selector); } + + public static function MAX(int $max, SelectorInterface ...$selector): AtMostModifier + { + return new AtMostModifier($max, ...$selector); + } }