Skip to content

Commit d21aefd

Browse files
committed
Use Subject to track pairs of Name and Path
1 parent 94ddfcd commit d21aefd

File tree

12 files changed

+141
-101
lines changed

12 files changed

+141
-101
lines changed

library/Message/Formatter/FirstResultStringFormatter.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,19 @@
1111

1212
use Respect\Validation\Message\Renderer;
1313
use Respect\Validation\Message\StringFormatter;
14-
use Respect\Validation\Name;
1514
use Respect\Validation\Result;
1615

1716
final readonly class FirstResultStringFormatter implements StringFormatter
1817
{
1918
/** @param array<string|int, mixed> $templates */
2019
public function format(Result $result, Renderer $renderer, array $templates): string
21-
{
22-
return $this->formatResult($result, $renderer, $templates, null);
23-
}
24-
25-
/** @param array<string|int, mixed> $templates */
26-
private function formatResult(Result $result, Renderer $renderer, array $templates, Name|null $parentName): string
2720
{
2821
if (!$result->hasCustomTemplate()) {
2922
foreach ($result->children as $child) {
30-
return $this->formatResult($child, $renderer, $templates, $result->name ?? $parentName);
23+
return $this->format($child, $renderer, $templates);
3124
}
3225
}
3326

34-
if ($parentName !== null) {
35-
$result = $result->withName($parentName);
36-
}
37-
3827
return $renderer->render($result, $templates);
3928
}
4029
}

library/Message/Formatter/NestedArrayFormatter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ public function format(Result $result, Renderer $renderer, array $templates): ar
2727
{
2828
if (count($result->children) === 0) {
2929
return [
30-
$result->path->value ?? $result->id->value => $renderer->render($result, $templates),
30+
$result->subject->path->value ?? $result->id->value => $renderer->render($result, $templates),
3131
];
3232
}
3333

3434
$messages = [];
3535
foreach ($result->children as $child) {
36-
$key = $child->path->value ?? $child->id->value;
36+
$key = $child->subject->path->value ?? $child->id->value;
3737
$messages[$key] = $this->format(
3838
$child->withoutName(),
3939
$renderer,

library/Message/Formatter/NestedListStringFormatter.php

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

1212
use Respect\Validation\Message\Renderer;
1313
use Respect\Validation\Message\StringFormatter;
14+
use Respect\Validation\Name;
1415
use Respect\Validation\Result;
1516

1617
use function array_filter;
@@ -27,7 +28,7 @@
2728
/** @param array<string|int, mixed> $templates */
2829
public function format(Result $result, Renderer $renderer, array $templates): string
2930
{
30-
return $this->formatRecursively($result, $renderer, $templates, 0);
31+
return $this->formatRecursively($result, $renderer, $templates, 0, null);
3132
}
3233

3334
/** @param array<string|int, mixed> $templates */
@@ -36,23 +37,31 @@ private function formatRecursively(
3637
Renderer $renderer,
3738
array $templates,
3839
int $depth,
40+
Name|null $displayedName,
3941
Result ...$siblings,
4042
): string {
4143
$formatted = '';
42-
$displayedName = null;
4344
if ($this->isVisible($result, ...$siblings)) {
4445
$indentation = str_repeat(' ', $depth * 2);
45-
$displayedName = $result->name;
46-
$formatted .= sprintf('%s- %s' . PHP_EOL, $indentation, $renderer->render($result, $templates));
46+
$formatted .= sprintf(
47+
'%s- %s' . PHP_EOL,
48+
$indentation,
49+
$renderer->render(
50+
$displayedName === $result->subject->name ? $result->withoutName() : $result,
51+
$templates,
52+
),
53+
);
54+
$displayedName ??= $result->subject->name;
4755
$depth++;
4856
}
4957

5058
foreach ($result->children as $child) {
5159
$formatted .= $this->formatRecursively(
52-
$displayedName === $child->name ? $child->withoutName() : $child,
60+
$child,
5361
$renderer,
5462
$templates,
5563
$depth,
64+
$displayedName,
5665
...array_filter($result->children, static fn(Result $sibling) => $sibling !== $child),
5766
);
5867
$formatted .= PHP_EOL;

library/Message/Formatter/TemplateResolver.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ public function getGivenTemplate(Result $result, array $templates): string|null
3232
return $result->template;
3333
}
3434

35-
if ($result->path !== null) {
36-
$templates = $this->filterByPath($result->path, $templates);
35+
if ($result->subject->path !== null) {
36+
$templates = $this->filterByPath($result->subject->path, $templates);
3737
}
3838

39-
foreach ([$result->path?->value, $result->name?->value, $result->id->value, '__root__'] as $key) {
39+
foreach ([$result->subject->path?->value, $result->subject->name?->value, $result->id->value, '__root__'] as $key) {
4040
if ($key === null || !isset($templates[$key])) {
4141
continue;
4242
}

library/Message/InterpolationRenderer.php

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
use Respect\Validation\Message\Formatter\TemplateResolver;
1414
use Respect\Validation\Message\Placeholder\Listed;
1515
use Respect\Validation\Message\Placeholder\Quoted;
16-
use Respect\Validation\Name;
1716
use Respect\Validation\Result;
1817

18+
use Respect\Validation\Subject;
1919
use function array_key_exists;
2020
use function is_array;
2121
use function is_bool;
@@ -36,7 +36,7 @@ public function __construct(
3636
/** @param array<string|int, mixed> $templates */
3737
public function render(Result $result, array $templates): string
3838
{
39-
$parameters = ['path' => $result->path, 'input' => $result->input, 'subject' => $this->getName($result)];
39+
$parameters = $this->getParameters($result->subject);
4040
$parameters += $result->parameters;
4141

4242
$givenTemplate = $this->templateResolver->getGivenTemplate($result, $templates);
@@ -89,24 +89,9 @@ private function placeholder(
8989
return $this->stringifier->stringify($value, 0) ?? print_r($value, true);
9090
}
9191

92-
private function getName(Result $result): mixed
92+
/** @return array<string, mixed> */
93+
private function getParameters(Subject $subject): array
9394
{
94-
if (array_key_exists('name', $result->parameters) && is_string($result->parameters['name'])) {
95-
return new Name($result->parameters['name']);
96-
}
97-
98-
if (array_key_exists('name', $result->parameters)) {
99-
return $result->parameters['name'];
100-
}
101-
102-
if ($result->name !== null) {
103-
return $result->name;
104-
}
105-
106-
if ($result->path?->value !== null) {
107-
return $result->path;
108-
}
109-
110-
return $result->input;
95+
return ['path' => $subject->path, 'input' => $subject->input, 'subject' => $subject];
11196
}
11297
}

library/Message/Stringifier/NameStringifier.php

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

1212
use Respect\Stringifier\Stringifier;
13-
use Respect\Validation\Name;
13+
use Respect\Validation\Subject;
1414

1515
use function sprintf;
1616

@@ -23,18 +23,26 @@ public function __construct(
2323

2424
public function stringify(mixed $raw, int $depth): string|null
2525
{
26-
if (!$raw instanceof Name) {
26+
if (!$raw instanceof Subject) {
2727
return null;
2828
}
2929

30-
if ($raw->path === null) {
31-
return $raw->value;
30+
if ($raw->path === null && $raw->name === null) {
31+
return $this->stringifier->stringify($raw->input, $depth);
32+
}
33+
34+
if ($raw->name === null) {
35+
return $this->stringifier->stringify($raw->path, $depth);
36+
}
37+
38+
if ($raw->path === null || $raw->isNamePrin === true) {
39+
return $raw->name->value;
3240
}
3341

3442
return sprintf(
3543
'%s (<- %s)',
3644
$this->stringifier->stringify($raw->path, $depth),
37-
$raw->value,
45+
$raw->name->value,
3846
);
3947
}
4048
}

library/Name.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,12 @@
99

1010
namespace Respect\Validation;
1111

12+
use function uniqid;
13+
1214
final readonly class Name
1315
{
1416
public function __construct(
1517
public string $value,
16-
public Path|null $path = null,
1718
) {
1819
}
19-
20-
public function withPath(Path $path): Name
21-
{
22-
return new self($this->value, $path);
23-
}
2420
}

library/Result.php

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@
2424
/** @param array<string, mixed> $parameters */
2525
public function __construct(
2626
public bool $hasPassed,
27-
public mixed $input,
27+
public Subject $subject,
2828
public Rule $rule,
2929
public Id $id,
3030
public array $parameters = [],
3131
public string $template = Rule::TEMPLATE_STANDARD,
3232
public bool $hasInvertedMode = false,
3333
public Name|null $name = null,
3434
public Result|null $adjacent = null,
35-
public Path|null $path = null,
3635
Result ...$children,
3736
) {
3837
$this->children = $children;
@@ -46,7 +45,7 @@ public static function of(
4645
array $parameters = [],
4746
string $template = Rule::TEMPLATE_STANDARD,
4847
): self {
49-
return new self($hasPassed, $input, $rule, Id::fromRule($rule), $parameters, $template);
48+
return new self($hasPassed, new Subject($input), $rule, Id::fromRule($rule), $parameters, $template);
5049
}
5150

5251
/** @param array<string, mixed> $parameters */
@@ -74,12 +73,12 @@ public function asAdjacentOf(Result $result, string $prefix): Result
7473
if ($this->allowsAdjacent()) {
7574
return clone ($result, [
7675
'id' => $this->id->withPrefix($prefix),
77-
'adjacent' => $this->withInput($result->input),
76+
'adjacent' => $this->withSubject($result->subject),
7877
]);
7978
}
8079

8180
return clone ($this, [
82-
'input' => $result->input,
81+
'subject' => $result->subject,
8382
'children' => array_map(
8483
static fn(Result $child) => $child->asAdjacentOf($result, $prefix),
8584
$this->children,
@@ -111,18 +110,8 @@ public function withIdFrom(Rule $rule): self
111110

112111
public function withPath(Path $path): self
113112
{
114-
if ($this->path === $path) {
115-
return $this;
116-
}
117-
118-
if ($this->path !== null) {
119-
$this->path->parent = $path;
120-
121-
return $this;
122-
}
123-
124113
return clone($this, [
125-
'path' => $path,
114+
'subject' => $this->subject->withPath($path),
126115
'adjacent' => $this->adjacent?->withPath($path),
127116
'children' => array_map(
128117
static fn(Result $child) => $child->withPath($path),
@@ -133,40 +122,30 @@ public function withPath(Path $path): self
133122

134123
public function withoutName(): self
135124
{
136-
if ($this->name === null) {
137-
return $this;
138-
}
139-
140125
return clone ($this, [
141-
'name' => null,
126+
'subject' => $this->subject->withoutName(),
142127
'adjacent' => $this->adjacent?->withoutName(),
143128
'children' => array_map(
144-
fn(Result $child) => $child->name === $this->name ? $child->withoutName() : $child,
129+
fn(Result $child) => $child->subject->name === $this->subject->name ? $child->withoutName() : $child,
145130
$this->children,
146131
),
147132
]);
148133
}
149134

150135
public function withChildren(Result ...$children): self
151136
{
152-
if ($this->path === null) {
153-
return clone($this, ['children' => $children]);
154-
}
155-
156-
return clone($this, ['children' => array_map(fn(Result $child) => $child->withPath($this->path), $children)]);
137+
return clone($this, [
138+
'children' => array_map(fn(Result $child) => $child->withSubject($this->subject), $children)
139+
]);
157140
}
158141

159142
public function withName(Name $name): self
160143
{
161-
if ($this->path !== null && $this->name?->path !== $this->path) {
162-
$name = $name->withPath($this->path);
163-
}
164-
165144
return clone($this, [
166-
'name' => $this->name ?? $name,
145+
'subject' => $this->subject->withName($name),
167146
'adjacent' => $this->adjacent?->withName($name),
168147
'children' => array_map(
169-
static fn(Result $child) => $child->path === null ? $child->withName($child->name ?? $name) : $child,
148+
static fn(Result $child) => $child->withName($name),
170149
$this->children,
171150
),
172151
]);
@@ -176,7 +155,7 @@ public function withNameFrom(Rule $rule): self
176155
{
177156
if ($rule instanceof Nameable && $rule->getName() !== null) {
178157
return clone($this, [
179-
'name' => $this->name ?? $rule->getName(),
158+
'subject' => $this->subject->withName2($rule->getName()),
180159
'adjacent' => $this->adjacent?->withNameFrom($rule),
181160
'children' => array_map(
182161
static fn(Result $child) => $child->withNameFrom($rule),
@@ -188,16 +167,12 @@ public function withNameFrom(Rule $rule): self
188167
return $this;
189168
}
190169

191-
public function withInput(mixed $input): self
170+
public function withSubject(Subject $subject): self
192171
{
193-
$currentInput = $this->input;
194-
195172
return clone($this, [
196-
'input' => $input,
197-
'children' => array_map(
198-
static fn(Result $child) => $child->input === $currentInput ? $child->withInput($input) : $child,
199-
$this->children,
200-
),
173+
'subject' => $this->subject->withMergeFrom($subject),
174+
'adjacent' => $this->adjacent?->withSubject($subject),
175+
'children' => array_map(static fn(Result $child) => $child->withSubject($subject), $this->children),
201176
]);
202177
}
203178

library/ResultQuery.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ public function findById(string $id): self|null
5252

5353
public function findByName(string $name): self|null
5454
{
55-
if ($this->result->name?->value === $name) {
55+
if ($this->result->subject->name?->value === $name) {
5656
return $this;
5757
}
5858

5959
foreach ($this->result->children as $child) {
6060
$resultQuery = clone ($this, ['result' => $child]);
61-
if ($child->name?->value === $name) {
61+
if ($child->subject->name?->value === $name) {
6262
return $resultQuery;
6363
}
6464

@@ -70,15 +70,15 @@ public function findByName(string $name): self|null
7070

7171
public function findByPath(string|int $path): self|null
7272
{
73-
if ($this->result->path?->value === $path) {
73+
if ($this->result->subject->path?->value === $path) {
7474
return $this;
7575
}
7676

7777
$paths = is_string($path) ? explode('.', $path) : [$path];
7878
$currentPath = array_shift($paths);
7979

8080
foreach ($this->result->children as $child) {
81-
if ($child->path?->value !== $currentPath) {
81+
if ($child->subject->path?->value !== $currentPath) {
8282
continue;
8383
}
8484

0 commit comments

Comments
 (0)