Skip to content

Commit 350f7b7

Browse files
committed
Added Logical rules
Added SingularRule, AndRule, OrRule
1 parent d58acf1 commit 350f7b7

File tree

10 files changed

+217
-3
lines changed

10 files changed

+217
-3
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Exceptions;
4+
5+
use Exception;
6+
7+
class LogicalRuleException extends Exception
8+
{
9+
protected const int UNABLE_TO_CREATE_RULE_CODE = 1;
10+
11+
public static function unableToCreateRule(string $message = 'Unable to create rule'): self
12+
{
13+
return new self($message, self::UNABLE_TO_CREATE_RULE_CODE);
14+
}
15+
}

src/Support/Collection.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Support;
4+
5+
/**
6+
* @template TKey of array-key
7+
* @template TValue of mixed
8+
*/
9+
class Collection
10+
{
11+
/** @var array<TKey, TValue> */
12+
protected array $items = [];
13+
14+
/**
15+
* @param array<TKey, TValue> $items
16+
*/
17+
public function __construct(array $items = [])
18+
{
19+
$this->items = $items;
20+
}
21+
22+
/**
23+
* @param TValue $item
24+
*
25+
* @return self<TKey, TValue>
26+
*/
27+
public function push(mixed $item): self
28+
{
29+
$this->items[] = $item;
30+
return $this;
31+
}
32+
33+
/**
34+
* @param TKey $key
35+
* @param TValue $value
36+
*
37+
* @return self<TKey, TValue>
38+
*/
39+
public function put(mixed $key, mixed $value): self
40+
{
41+
$this->items[$key] = $value;
42+
return $this;
43+
}
44+
45+
/**
46+
* @param ?callable(TValue $item): bool $callable
47+
*
48+
* @return ?TValue
49+
*/
50+
public function first(?callable $callable = null): mixed
51+
{
52+
return is_null($callable)
53+
? reset($this->items) ?: null
54+
: array_find($this->items, $callable);
55+
}
56+
57+
public function isNotEmpty(): bool
58+
{
59+
return !empty($this->items);
60+
}
61+
62+
public function isEmpty(): bool
63+
{
64+
return !$this->isNotEmpty();
65+
}
66+
67+
/**
68+
* @param callable(TValue $item): bool $callable
69+
*/
70+
public function every(callable $callable): bool
71+
{
72+
return array_all($this->items, $callable);
73+
}
74+
75+
/**
76+
* @param callable(TValue $item): bool $callable
77+
*/
78+
public function some(callable $callable): bool
79+
{
80+
return array_any($this->items, $callable);
81+
}
82+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation\Contracts;
4+
5+
interface RuleEvaluator
6+
{
7+
public function evaluate(mixed $value): bool;
8+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation\Contracts;
4+
5+
use Nuxtifyts\PhpDto\Exceptions\ValidationRuleException;
6+
use Nuxtifyts\PhpDto\Support\Collection;
7+
8+
interface RuleGroup
9+
{
10+
/** @var Collection<array-key, RuleEvaluator> */
11+
public Collection $rules { get; }
12+
13+
/**
14+
* @throws ValidationRuleException
15+
*/
16+
public function addRule(RuleEvaluator $rule): static;
17+
}

src/Validation/Logic/AndRule.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation\Logic;
4+
5+
use Nuxtifyts\PhpDto\Validation\Contracts\RuleEvaluator;
6+
7+
class AndRule extends LogicalRule
8+
{
9+
public function evaluate(mixed $value): bool
10+
{
11+
return $this->rules->every(
12+
static fn (RuleEvaluator $rule) => $rule->evaluate($value)
13+
);
14+
}
15+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation\Logic;
4+
5+
use Nuxtifyts\PhpDto\Support\Collection;
6+
use Nuxtifyts\PhpDto\Validation\Contracts\RuleEvaluator;
7+
use Nuxtifyts\PhpDto\Validation\Contracts\RuleGroup;
8+
9+
abstract class LogicalRule implements RuleGroup, RuleEvaluator
10+
{
11+
/** @var ?Collection<array-key, RuleEvaluator> */
12+
protected ?Collection $_rules = null;
13+
14+
/** @var Collection<array-key, RuleEvaluator> */
15+
public Collection $rules {
16+
get {
17+
return $this->_rules ??= new Collection();
18+
}
19+
}
20+
21+
public function addRule(RuleEvaluator $rule): static
22+
{
23+
$this->rules->push($rule);
24+
return $this;
25+
}
26+
}

src/Validation/Logic/OrRule.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation\Logic;
4+
5+
use Nuxtifyts\PhpDto\Validation\Contracts\RuleEvaluator;
6+
7+
class OrRule extends LogicalRule
8+
{
9+
public function evaluate(mixed $value): bool
10+
{
11+
return $this->rules->some(
12+
static fn (RuleEvaluator $rule) => $rule->evaluate($value)
13+
);
14+
}
15+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation\Logic;
4+
5+
use Nuxtifyts\PhpDto\Exceptions\LogicalRuleException;
6+
use Nuxtifyts\PhpDto\Validation\Contracts\RuleEvaluator;
7+
use Override;
8+
9+
class SingularRule extends LogicalRule
10+
{
11+
/**
12+
* @throws LogicalRuleException
13+
*/
14+
#[Override]
15+
public function addRule(RuleEvaluator $rule): static
16+
{
17+
if ($this->rules->isNotEmpty()) {
18+
throw LogicalRuleException::unableToCreateRule('SingularRule can only have one rule');
19+
}
20+
21+
$this->rules->push($rule);
22+
return $this;
23+
}
24+
25+
public function evaluate(mixed $value): bool
26+
{
27+
return (bool) $this->rules->first()?->evaluate($value);
28+
}
29+
}

src/Validation/RuleContext.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation;
4+
5+
class RuleContext
6+
{
7+
8+
}

src/Validation/Rules/ValidationRule.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
namespace Nuxtifyts\PhpDto\Validation\Rules;
44

55
use Nuxtifyts\PhpDto\Exceptions\ValidationRuleException;
6+
use Nuxtifyts\PhpDto\Validation\Contracts\RuleEvaluator;
67

7-
interface ValidationRule
8+
interface ValidationRule extends RuleEvaluator
89
{
910
public string $name { get; }
1011

11-
public function evaluate(mixed $value): bool;
12-
1312
/**
1413
* @param ?array<string, mixed> $parameters
1514
*

0 commit comments

Comments
 (0)