Skip to content

Commit

Permalink
Improve composite-based rules
Browse files Browse the repository at this point in the history
Because the rules' property is read-only, there aren't many reasons not
to expose that, especially since we already expose the rules anyways.

I also changed the implementation of "OneOf" because we don't see "xor"
enough these days.

Signed-off-by: Henrique Moody <[email protected]>
  • Loading branch information
henriquemoody committed Mar 6, 2024
1 parent 24885e4 commit df16dda
Show file tree
Hide file tree
Showing 6 changed files with 10 additions and 8 deletions.
2 changes: 1 addition & 1 deletion library/Rules/AllOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ final class AllOf extends Composite

public function evaluate(mixed $input): Result
{
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->getRules());
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->rules);
$valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry && $result->isValid, true);
$failed = array_filter($children, static fn (Result $result): bool => !$result->isValid);
$template = self::TEMPLATE_SOME;
Expand Down
2 changes: 1 addition & 1 deletion library/Rules/AnyOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class AnyOf extends Composite
{
public function evaluate(mixed $input): Result
{
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->getRules());
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->rules);
$valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry || $result->isValid, false);

return (new Result($valid, $input, $this))->withChildren(...$children);
Expand Down
4 changes: 2 additions & 2 deletions library/Rules/Core/Composite.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ abstract class Composite implements Validatable
use DeprecatedValidatableMethods;

/** @var non-empty-array<Validatable> */
private readonly array $rules;
protected readonly array $rules;

private ?string $name = null;

Expand All @@ -38,7 +38,7 @@ public function getRules(): array

public function setName(string $name): static
{
foreach ($this->getRules() as $rule) {
foreach ($this->rules as $rule) {
if ($rule->getName() && $this->name !== $rule->getName()) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion library/Rules/NoneOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class NoneOf extends Composite
{
public function evaluate(mixed $input): Result
{
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input)->withInvertedMode(), $this->getRules());
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input)->withInvertedMode(), $this->rules);
$valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry && $result->isValid, true);

return (new Result($valid, $input, $this))->withChildren(...$children);
Expand Down
6 changes: 3 additions & 3 deletions library/Rules/OneOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ final class OneOf extends Composite
{
public function evaluate(mixed $input): Result
{
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->getRules());
$count = array_reduce($children, static fn (int $carry, Result $result) => $carry + (int) $result->isValid, 0);
$children = array_map(static fn (Rule $rule) => $rule->evaluate($input), $this->rules);
$valid = array_reduce($children, static fn (bool $carry, Result $result) => $carry xor $result->isValid, false);

return (new Result($count === 1, $input, $this))->withChildren(...$children);
return (new Result($valid, $input, $this))->withChildren(...$children);
}
}
2 changes: 2 additions & 0 deletions tests/unit/Rules/AnyOfTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ final class AnyOfTest extends RuleTestCase
public static function providerForValidInput(): iterable
{
yield 'fail, pass' => [new AnyOf(Stub::fail(1), Stub::pass(1)), []];
yield 'pass, fail' => [new AnyOf(Stub::pass(1), Stub::fail(1)), []];
yield 'fail, fail, pass' => [new AnyOf(Stub::fail(1), Stub::fail(1), Stub::pass(1)), []];
yield 'fail, pass, fail' => [new AnyOf(Stub::fail(1), Stub::pass(1), Stub::fail(1)), []];
yield 'pass, fail, fail' => [new AnyOf(Stub::pass(1), Stub::fail(1), Stub::fail(1)), []];
}

/** @return iterable<string, array{AnyOf, mixed}> */
Expand Down

0 comments on commit df16dda

Please sign in to comment.