Skip to content

Commit 05c1e66

Browse files
committed
wipg
1 parent 4d8bb8a commit 05c1e66

File tree

9 files changed

+198
-56
lines changed

9 files changed

+198
-56
lines changed

src/PhpTypes/MultiValueNode.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Orisai\ObjectMapper\PhpTypes;
4+
5+
final class MultiValueNode implements Node
6+
{
7+
8+
private string $name;
9+
10+
private ?Node $key;
11+
12+
private Node $item;
13+
14+
public function __construct(string $name, ?Node $key, Node $item)
15+
{
16+
$this->name = $name;
17+
$this->key = $key;
18+
$this->item = $item;
19+
}
20+
21+
public function __toString(): string
22+
{
23+
return $this->name
24+
. '<'
25+
. ($this->key !== null ? (string) $this->key : '')
26+
. ((string) $this->item)
27+
. '>';
28+
}
29+
30+
}

src/Rules/AllOfRule.php

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,29 +67,19 @@ protected function createCompoundType(): CompoundType
6767
*/
6868
public function getExpectedInputType(Args $args, TypeContext $context): Node
6969
{
70-
$nodes = [];
71-
foreach ($args->rules as $ruleMeta) {
72-
$rule = $context->getRule($ruleMeta->getType());
73-
$ruleArgs = $ruleMeta->getArgs();
74-
$nodes[] = $rule->getExpectedInputType($ruleArgs, $context);
75-
}
76-
77-
return CompoundNode::createAndType($nodes);
70+
return CompoundNode::createAndType(
71+
$this->getExpectedInputTypeNodes($args, $context),
72+
);
7873
}
7974

8075
/**
8176
* @param CompoundRuleArgs $args
8277
*/
8378
public function getReturnType(Args $args, TypeContext $context): Node
8479
{
85-
$nodes = [];
86-
foreach ($args->rules as $ruleMeta) {
87-
$rule = $context->getRule($ruleMeta->getType());
88-
$ruleArgs = $ruleMeta->getArgs();
89-
$nodes[] = $rule->getReturnType($ruleArgs, $context);
90-
}
91-
92-
return CompoundNode::createAndType($nodes);
80+
return CompoundNode::createAndType(
81+
$this->getReturnTypeNodes($args, $context),
82+
);
9383
}
9484

9585
}

src/Rules/AnyOfRule.php

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,29 +66,19 @@ protected function createCompoundType(): CompoundType
6666
*/
6767
public function getExpectedInputType(Args $args, TypeContext $context): Node
6868
{
69-
$nodes = [];
70-
foreach ($args->rules as $ruleMeta) {
71-
$rule = $context->getRule($ruleMeta->getType());
72-
$ruleArgs = $ruleMeta->getArgs();
73-
$nodes[] = $rule->getExpectedInputType($ruleArgs, $context);
74-
}
75-
76-
return CompoundNode::createOrType($nodes);
69+
return CompoundNode::createOrType(
70+
$this->getExpectedInputTypeNodes($args, $context),
71+
);
7772
}
7873

7974
/**
8075
* @param CompoundRuleArgs $args
8176
*/
8277
public function getReturnType(Args $args, TypeContext $context): Node
8378
{
84-
$nodes = [];
85-
foreach ($args->rules as $ruleMeta) {
86-
$rule = $context->getRule($ruleMeta->getType());
87-
$ruleArgs = $ruleMeta->getArgs();
88-
$nodes[] = $rule->getReturnType($ruleArgs, $context);
89-
}
90-
91-
return CompoundNode::createOrType($nodes);
79+
return CompoundNode::createOrType(
80+
$this->getReturnTypeNodes($args, $context),
81+
);
9282
}
9383

9484
}

src/Rules/ArrayOfRule.php

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
use Orisai\ObjectMapper\Exception\InvalidData;
1111
use Orisai\ObjectMapper\Exception\ValueDoesNotMatch;
1212
use Orisai\ObjectMapper\Meta\Compile\RuleCompileMeta;
13+
use Orisai\ObjectMapper\PhpTypes\MultiValueNode;
1314
use Orisai\ObjectMapper\PhpTypes\Node;
14-
use Orisai\ObjectMapper\PhpTypes\SimpleNode;
1515
use Orisai\ObjectMapper\Types\ArrayType;
1616
use Orisai\ObjectMapper\Types\Value;
1717
use Orisai\Utils\Arrays\ArrayMerger;
@@ -79,7 +79,7 @@ public function getArgsType(): string
7979
}
8080

8181
/**
82-
* @param mixed $value
82+
* @param mixed $value
8383
* @param ArrayOfArgs $args
8484
* @return array<mixed>
8585
* @throws ValueDoesNotMatch
@@ -165,14 +165,10 @@ public function processValue($value, Args $args, FieldContext $context): array
165165
*/
166166
public function createType(Args $args, TypeContext $context): ArrayType
167167
{
168-
$itemMeta = $args->itemRuleMeta;
169-
$itemRule = $context->getRule($itemMeta->getType());
170-
$itemArgs = $itemMeta->getArgs();
168+
[$keyRule, $keyArgs] = $this->getKeyRuleArgs($args, $context);
169+
[$itemRule, $itemArgs] = $this->getItemRuleArgs($args, $context);
171170

172-
$keyMeta = $args->keyRuleMeta;
173-
if ($keyMeta !== null) {
174-
$keyRule = $context->getRule($keyMeta->getType());
175-
$keyArgs = $keyMeta->getArgs();
171+
if ($keyRule !== null && $keyArgs !== null) {
176172
$keyType = $keyRule->createType($keyArgs, $context);
177173
}
178174

@@ -197,15 +193,59 @@ public function createType(Args $args, TypeContext $context): ArrayType
197193
*/
198194
public function getExpectedInputType(Args $args, TypeContext $context): Node
199195
{
200-
return new SimpleNode('TODO');
196+
[$keyRule, $keyArgs] = $this->getKeyRuleArgs($args, $context);
197+
[$itemRule, $itemArgs] = $this->getItemRuleArgs($args, $context);
198+
199+
if ($keyRule !== null && $keyArgs !== null) {
200+
$keyNode = $keyRule->getExpectedInputType($keyArgs, $context);
201+
}
202+
203+
return new MultiValueNode(
204+
$this->getNodeName($args),
205+
$keyNode ?? null,
206+
$itemRule->getExpectedInputType($itemArgs, $context),
207+
);
201208
}
202209

203210
/**
204211
* @param ArrayOfArgs $args
205212
*/
206213
public function getReturnType(Args $args, TypeContext $context): Node
207214
{
208-
return new SimpleNode('TODO');
215+
[$keyRule, $keyArgs] = $this->getKeyRuleArgs($args, $context);
216+
[$itemRule, $itemArgs] = $this->getItemRuleArgs($args, $context);
217+
218+
if ($keyRule !== null && $keyArgs !== null) {
219+
$keyNode = $keyRule->getReturnType($keyArgs, $context);
220+
}
221+
222+
return new MultiValueNode(
223+
$this->getNodeName($args),
224+
$keyNode ?? null,
225+
$itemRule->getReturnType($itemArgs, $context),
226+
);
227+
}
228+
229+
private function getNodeName(ArrayOfArgs $args): string
230+
{
231+
return ($args->minItems ?? 0) > 0 ? 'non-empty-array' : 'array';
232+
}
233+
234+
/**
235+
* @return array{Rule<Args>, Args}|array{null, null}
236+
*/
237+
private function getKeyRuleArgs(ArrayOfArgs $args, TypeContext $context): array
238+
{
239+
$keyRuleMeta = $args->keyRuleMeta;
240+
241+
if ($keyRuleMeta === null) {
242+
return [null, null];
243+
}
244+
245+
$keyRule = $context->getRule($keyRuleMeta->getType());
246+
$keyArgs = $keyRuleMeta->getArgs();
247+
248+
return [$keyRule, $keyArgs];
209249
}
210250

211251
}

src/Rules/CompoundRule.php

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use Orisai\ObjectMapper\Context\RuleArgsContext;
99
use Orisai\ObjectMapper\Context\TypeContext;
1010
use Orisai\ObjectMapper\Meta\Compile\RuleCompileMeta;
11+
use Orisai\ObjectMapper\Meta\Runtime\RuleRuntimeMeta;
12+
use Orisai\ObjectMapper\PhpTypes\Node;
1113
use Orisai\ObjectMapper\Types\CompoundType;
1214
use function count;
1315
use function sprintf;
@@ -64,14 +66,53 @@ public function createType(Args $args, TypeContext $context): CompoundType
6466
$type = $this->createCompoundType();
6567

6668
foreach ($args->rules as $key => $nestedRuleMeta) {
67-
$nestedRule = $context->getRule($nestedRuleMeta->getType());
68-
$nestedRuleArgs = $nestedRuleMeta->getArgs();
69-
$type->addSubtype($key, $nestedRule->createType($nestedRuleArgs, $context));
69+
[$subNodeRule, $subNodeArgs] = $this->getSubNodeRuleArgs($nestedRuleMeta, $context);
70+
$type->addSubtype($key, $subNodeRule->createType($subNodeArgs, $context));
7071
}
7172

7273
return $type;
7374
}
7475

7576
abstract protected function createCompoundType(): CompoundType;
7677

78+
/**
79+
* @param RuleRuntimeMeta<Args> $meta
80+
* @return array{Rule<Args>, Args}
81+
*/
82+
private function getSubNodeRuleArgs(RuleRuntimeMeta $meta, TypeContext $context): array
83+
{
84+
$rule = $context->getRule($meta->getType());
85+
$args = $meta->getArgs();
86+
87+
return [$rule, $args];
88+
}
89+
90+
/**
91+
* @return array<int, Node>
92+
*/
93+
protected function getExpectedInputTypeNodes(CompoundRuleArgs $args, TypeContext $context): array
94+
{
95+
$nodes = [];
96+
foreach ($args->rules as $ruleMeta) {
97+
[$subNodeRule, $subNodeArgs] = $this->getSubNodeRuleArgs($ruleMeta, $context);
98+
$nodes[] = $subNodeRule->getExpectedInputType($subNodeArgs, $context);
99+
}
100+
101+
return $nodes;
102+
}
103+
104+
/**
105+
* @return array<int, Node>
106+
*/
107+
protected function getReturnTypeNodes(CompoundRuleArgs $args, TypeContext $context): array
108+
{
109+
$nodes = [];
110+
foreach ($args->rules as $ruleMeta) {
111+
[$subNodeRule, $subNodeArgs] = $this->getSubNodeRuleArgs($ruleMeta, $context);
112+
$nodes[] = $subNodeRule->getReturnType($subNodeArgs, $context);
113+
}
114+
115+
return $nodes;
116+
}
117+
77118
}

src/Rules/DateTimeRule.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Orisai\ObjectMapper\Context\RuleArgsContext;
1414
use Orisai\ObjectMapper\Context\TypeContext;
1515
use Orisai\ObjectMapper\Exception\ValueDoesNotMatch;
16+
use Orisai\ObjectMapper\PhpTypes\CompoundNode;
1617
use Orisai\ObjectMapper\PhpTypes\Node;
1718
use Orisai\ObjectMapper\PhpTypes\SimpleNode;
1819
use Orisai\ObjectMapper\Types\SimpleValueType;
@@ -179,15 +180,26 @@ public function createType(Args $args, TypeContext $context): SimpleValueType
179180
*/
180181
public function getExpectedInputType(Args $args, TypeContext $context): Node
181182
{
182-
return new SimpleNode('TODO');
183+
if ($args->format === self::FormatTimestamp) {
184+
return new SimpleNode('int');
185+
}
186+
187+
if ($args->format === self::FormatAny) {
188+
return CompoundNode::createOrType([
189+
new SimpleNode('int'),
190+
new SimpleNode('string'),
191+
]);
192+
}
193+
194+
return new SimpleNode('string');
183195
}
184196

185197
/**
186198
* @param DateTimeArgs $args
187199
*/
188200
public function getReturnType(Args $args, TypeContext $context): Node
189201
{
190-
return new SimpleNode('TODO');
202+
return new SimpleNode($args->type);
191203
}
192204

193205
}

src/Rules/ListOfRule.php

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
use Orisai\ObjectMapper\Exception\InvalidData;
1111
use Orisai\ObjectMapper\Exception\ValueDoesNotMatch;
1212
use Orisai\ObjectMapper\Meta\Compile\RuleCompileMeta;
13+
use Orisai\ObjectMapper\PhpTypes\MultiValueNode;
1314
use Orisai\ObjectMapper\PhpTypes\Node;
14-
use Orisai\ObjectMapper\PhpTypes\SimpleNode;
1515
use Orisai\ObjectMapper\Types\ArrayType;
1616
use Orisai\ObjectMapper\Types\SimpleValueType;
1717
use Orisai\ObjectMapper\Types\Value;
@@ -146,9 +146,7 @@ public function processValue($value, Args $args, FieldContext $context): array
146146
*/
147147
public function createType(Args $args, TypeContext $context): ArrayType
148148
{
149-
$itemMeta = $args->itemRuleMeta;
150-
$itemRule = $context->getRule($itemMeta->getType());
151-
$itemArgs = $itemMeta->getArgs();
149+
[$itemRule, $itemArgs] = $this->getItemRuleArgs($args, $context);
152150

153151
$type = ArrayType::forList(
154152
$this->createKeyType(),
@@ -179,15 +177,32 @@ private function createKeyType(): SimpleValueType
179177
*/
180178
public function getExpectedInputType(Args $args, TypeContext $context): Node
181179
{
182-
return new SimpleNode('TODO');
180+
[$itemRule, $itemArgs] = $this->getItemRuleArgs($args, $context);
181+
182+
return new MultiValueNode(
183+
$this->getNodeName($args),
184+
null,
185+
$itemRule->getExpectedInputType($itemArgs, $context),
186+
);
183187
}
184188

185189
/**
186190
* @param MultiValueArgs $args
187191
*/
188192
public function getReturnType(Args $args, TypeContext $context): Node
189193
{
190-
return new SimpleNode('TODO');
194+
[$itemRule, $itemArgs] = $this->getItemRuleArgs($args, $context);
195+
196+
return new MultiValueNode(
197+
$this->getNodeName($args),
198+
null,
199+
$itemRule->getReturnType($itemArgs, $context),
200+
);
201+
}
202+
203+
private function getNodeName(MultiValueArgs $args): string
204+
{
205+
return ($args->minItems ?? 0) > 0 ? 'non-empty-list' : 'list';
191206
}
192207

193208
}

src/Rules/MultiValueRule.php

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

33
namespace Orisai\ObjectMapper\Rules;
44

5+
use Orisai\ObjectMapper\Args\Args;
6+
use Orisai\ObjectMapper\Context\TypeContext;
7+
58
/**
69
* @phpstan-template T of MultiValueArgs
710
* @phpstan-implements Rule<T>
@@ -16,4 +19,17 @@ abstract class MultiValueRule implements Rule
1619
MaxItems = 'maxItems',
1720
MergeDefaults = 'mergeDefaults';
1821

22+
/**
23+
* @return array{Rule<Args>, Args}
24+
*/
25+
protected function getItemRuleArgs(MultiValueArgs $args, TypeContext $context): array
26+
{
27+
$itemRuleMeta = $args->itemRuleMeta;
28+
29+
$itemRule = $context->getRule($itemRuleMeta->getType());
30+
$itemArgs = $itemRuleMeta->getArgs();
31+
32+
return [$itemRule, $itemArgs];
33+
}
34+
1935
}

0 commit comments

Comments
 (0)