Skip to content

Commit fc9bfc0

Browse files
committed
Use Path object
1 parent 48e0082 commit fc9bfc0

File tree

11 files changed

+64
-42
lines changed

11 files changed

+64
-42
lines changed

library/FailedResultIterator.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
use Countable;
1313
use Iterator;
14-
1514
use RecursiveIterator;
15+
1616
use function array_filter;
1717
use function array_key_exists;
1818
use function array_map;
@@ -26,7 +26,7 @@
2626
/**
2727
* @implements Iterator<int, Result>
2828
*/
29-
final class FailedResultIterator implements Iterator, Countable, \RecursiveIterator
29+
final class FailedResultIterator implements Iterator, Countable, RecursiveIterator
3030
{
3131
private array $children;
3232

@@ -43,7 +43,7 @@ public function extractDeduplicatedChildren(): array
4343
$duplicateCounters = [];
4444
foreach ($this->result->children as $child) {
4545
if ($child->path !== null) {
46-
$deduplicatedResults[$child->path] = $child->isValid ? null : $child;
46+
$deduplicatedResults[$child->path->value] = $child->isValid ? null : $child;
4747
continue;
4848
}
4949

@@ -62,7 +62,7 @@ public function extractDeduplicatedChildren(): array
6262

6363
return array_map(
6464
function (Result $child): Result {
65-
if ($this->result->path !== null && $child->path !== null && $child->path !== $this->result->path) {
65+
if ($this->result->path !== null && $child->path !== null && $child->path->isEqual($this->result->path)) {
6666
return $child->withPath($this->result->path);
6767
}
6868

@@ -116,7 +116,7 @@ public function hasChildren(): bool
116116
return $this->result->children !== [];
117117
}
118118

119-
public function getChildren(): ?RecursiveIterator
119+
public function getChildren(): ?self
120120
{
121121
if (!$this->hasChildren()) {
122122
return null;

library/Message/Placeholder/Path.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,24 @@
1212
final class Path
1313
{
1414
public function __construct(
15-
private readonly int|string $value
15+
public readonly int|string $value,
16+
public readonly ?Path $child = null
1617
) {
1718
}
1819

19-
public function getValue(): int|string
20+
public function withParent(int|string $value): self
2021
{
21-
return $this->value;
22+
return new self($value, $this);
23+
}
24+
25+
public function isEqual(Path $path): bool
26+
{
27+
return $this->value === $path->value
28+
&& $this->child?->isEqual($path->child) ?? true;
29+
}
30+
31+
public function getDeepest(): Path
32+
{
33+
return $this->child?->getDeepest() ?? $this;
2234
}
2335
}

library/Message/StandardFormatter.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
namespace Respect\Validation\Message;
1111

1212
use Respect\Validation\Exceptions\ComponentException;
13-
use Respect\Validation\Result;
1413
use Respect\Validation\FailedResultIterator;
14+
use Respect\Validation\Result;
1515

1616
use function array_filter;
1717
use function array_reduce;
@@ -103,7 +103,7 @@ public function array(Result $result, array $templates, Translator $translator):
103103
$deduplicatedChildren = new FailedResultIterator($result);
104104
if (count($deduplicatedChildren) === 0 || $this->isFinalTemplate($result, $selectedTemplates)) {
105105
return [
106-
$result->getDeepestPath() ?? $result->id => $this->renderer->render(
106+
$result->path?->getDeepest()->value ?? $result->id => $this->renderer->render(
107107
$this->getTemplated($result->withDeepestPath(), $selectedTemplates),
108108
$translator
109109
),
@@ -112,7 +112,7 @@ public function array(Result $result, array $templates, Translator $translator):
112112

113113
$messages = [];
114114
foreach ($deduplicatedChildren as $child) {
115-
$key = $child->getDeepestPath() ?? $child->id;
115+
$key = $child?->path?->getDeepest()->value ?? $child->id;
116116
$messages[$key] = $this->array(
117117
$this->resultWithPath($result, $child),
118118
$this->selectTemplates($child, $selectedTemplates),
@@ -139,7 +139,7 @@ public function array(Result $result, array $templates, Translator $translator):
139139
return $messages;
140140
}
141141

142-
public function resultWithPath(Result $parent, Result $child): Result
142+
private function resultWithPath(Result $parent, Result $child): Result
143143
{
144144
if ($parent->path !== null && $child->path !== null && $child->path !== $parent->path) {
145145
return $child->withPath($parent->path);
@@ -194,7 +194,7 @@ private function getTemplated(Result $result, array $templates): Result
194194
return $result;
195195
}
196196

197-
foreach ([$result->path, $result->name, $result->id, '__root__'] as $key) {
197+
foreach ([$result->path?->value, $result->name, $result->id, '__root__'] as $key) {
198198
if (!isset($templates[$key])) {
199199
continue;
200200
}
@@ -216,7 +216,7 @@ private function getTemplated(Result $result, array $templates): Result
216216
*/
217217
private function isFinalTemplate(Result $result, array $templates): bool
218218
{
219-
$keys = [$result->path, $result->name, $result->id];
219+
$keys = [$result->path?->value, $result->name, $result->id];
220220
foreach ($keys as $key) {
221221
if (isset($templates[$key]) && is_string($templates[$key])) {
222222
return true;
@@ -243,7 +243,7 @@ private function isFinalTemplate(Result $result, array $templates): bool
243243
*/
244244
private function selectTemplates(Result $result, array $templates): array
245245
{
246-
foreach ([$result->path, $result->name, $result->id] as $key) {
246+
foreach ([$result->path?->value, $result->name, $result->id] as $key) {
247247
if (isset($templates[$key]) && is_array($templates[$key])) {
248248
return $templates[$key];
249249
}

library/Message/StandardRenderer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function __construct(
3737
public function render(Result $result, Translator $translator, ?string $template = null): string
3838
{
3939
$parameters = $result->parameters;
40-
$parameters['path'] = $result->path !== null ? new Path($result->path) : null;
40+
$parameters['path'] = $result->path;
4141
$parameters['input'] = $result->input;
4242

4343
$builtName = $result->name ?? $parameters['path'] ?? $this->placeholder('input', $result->input, $translator);

library/Message/Stringifier/PathStringifier.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ public function stringify(mixed $raw, int $depth): ?string
2626
return null;
2727
}
2828

29-
return $this->quoter->quote('.' . $raw->getValue(), $depth);
29+
$path = $raw;
30+
$string = $path->value;
31+
while ($path = $path->child) {
32+
$string .= '.' . $path->value;
33+
}
34+
35+
return $this->quoter->quote('.' . $string, $depth);
3036
}
3137
}

library/Result.php

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace Respect\Validation;
1111

12+
use Respect\Validation\Message\Placeholder\Path;
1213
use Respect\Validation\Rules\Core\Nameable;
1314

1415
use function array_filter;
@@ -40,7 +41,7 @@ public function __construct(
4041
public readonly ?string $name = null,
4142
?string $id = null,
4243
public readonly ?Result $adjacent = null,
43-
public readonly string|int|null $path = null,
44+
public readonly ?Path $path = null,
4445
Result ...$children,
4546
) {
4647
$this->id = $id ?? lcfirst(substr((string) strrchr($rule::class, '\\'), 1));
@@ -111,39 +112,40 @@ public function withIdFrom(Rule $rule): self
111112
return $this->clone(id: lcfirst(substr((string) strrchr($rule::class, '\\'), 1)));
112113
}
113114

114-
public function withPath(string|int $path): self
115+
public function withPath(Path $path): self
115116
{
116117
return $this->clone(
117118
adjacent: $this->adjacent?->withPath($path),
118-
path: $this->path === null ? $path : $path . '.' . $this->path,
119+
path: $path,
119120
);
120121
}
121122

122-
public function withDeepestPath(): self
123+
public function withChildPath(string|int $path): self
123124
{
124-
$path = $this->getDeepestPath();
125-
if ($path === null || $path === (string) $this->path) {
126-
return $this;
127-
}
128-
129125
return $this->clone(
130-
adjacent: $this->adjacent?->withPath($path),
131-
path: $path,
126+
adjacent: $this->adjacent?->withChildPath($path),
127+
path: new Path($path, $this->path),
132128
);
133129
}
134130

135-
public function getDeepestPath(): ?string
131+
public function withParentPath(string|int $path): self
136132
{
137-
if ($this->path === null) {
138-
return null;
139-
}
133+
return $this->clone(
134+
adjacent: $this->adjacent?->withParentPath($path),
135+
path: $this->path?->withParent($path) ?? new Path($path),
136+
);
137+
}
140138

141-
$paths = explode('.', (string) $this->path);
142-
if (count($paths) === 1) {
143-
return (string) $this->path;
139+
public function withDeepestPath(): self
140+
{
141+
if ($this->path === null || $this->path->child === null || $this->path->getDeepest() === $this->path) {
142+
return $this;
144143
}
145144

146-
return end($paths);
145+
return $this->clone(
146+
adjacent: $this->adjacent?->withDeepestPath(),
147+
path: $this->path?->getDeepest(),
148+
);
147149
}
148150

149151
public function withPrefix(string $prefix): self
@@ -250,7 +252,7 @@ private function clone(
250252
?string $name = null,
251253
?string $id = null,
252254
?Result $adjacent = null,
253-
string|int|null $path = null,
255+
?Path $path = null,
254256
?array $children = null
255257
): self {
256258
return new self(

library/Rules/Each.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected function evaluateNonEmptyArray(array $input): Result
2828
{
2929
$children = [];
3030
foreach ($input as $key => $value) {
31-
$children[] = $this->rule->evaluate($value)->withPath($key);
31+
$children[] = $this->rule->evaluate($value)->withParentPath($key);
3232
}
3333
$isValid = array_reduce($children, static fn ($carry, $childResult) => $carry && $childResult->isValid, true);
3434

library/Rules/Key.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ public function evaluate(mixed $input): Result
3737
return $keyExistsResult->withNameFrom($this->rule);
3838
}
3939

40-
return $this->rule->evaluate($input[$this->key])->withPath($this->key);
40+
return $this->rule->evaluate($input[$this->key])->withParentPath($this->key);
4141
}
4242
}

library/Rules/KeyExists.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use ArrayAccess;
1313
use Attribute;
14+
use Respect\Validation\Message\Placeholder\Path;
1415
use Respect\Validation\Message\Template;
1516
use Respect\Validation\Result;
1617
use Respect\Validation\Rules\Core\KeyRelated;
@@ -38,7 +39,7 @@ public function getKey(): int|string
3839

3940
public function evaluate(mixed $input): Result
4041
{
41-
return new Result($this->hasKey($input), $input, $this, path: $this->key);
42+
return new Result($this->hasKey($input), $input, $this, path: new Path($this->key));
4243
}
4344

4445
private function hasKey(mixed $input): bool

library/Rules/Property.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function evaluate(mixed $input): Result
3434

3535
return $this->rule
3636
->evaluate($this->extractPropertyValue($input, $this->propertyName))
37-
->withPath($this->propertyName);
37+
->withParentPath($this->propertyName);
3838
}
3939

4040
private function extractPropertyValue(object $input, string $property): mixed

library/Rules/PropertyExists.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Attribute;
1313
use ReflectionObject;
14+
use Respect\Validation\Message\Placeholder\Path;
1415
use Respect\Validation\Message\Template;
1516
use Respect\Validation\Result;
1617
use Respect\Validation\Rules\Core\Standard;
@@ -35,7 +36,7 @@ public function evaluate(mixed $input): Result
3536
$this->hasProperty($input),
3637
$input,
3738
$this,
38-
path: $this->propertyName,
39+
path: new Path($this->propertyName),
3940
);
4041
}
4142

0 commit comments

Comments
 (0)