Skip to content

Commit 7d3800c

Browse files
committed
optimize schema
1 parent 31b4505 commit 7d3800c

6 files changed

Lines changed: 148 additions & 400 deletions

File tree

src/Parser.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ public function literal(bool|float|int|string $literal): LiteralSchema
101101
* @param array<string, SchemaInterface> $fieldNameToSchema
102102
* @param class-string $classname
103103
*/
104-
public function object(array $fieldNameToSchema, string $classname = \stdClass::class): ObjectSchema
104+
public function object(array $fieldNameToSchema, string $classname = \stdClass::class, bool $construct = false): ObjectSchema
105105
{
106-
return new ObjectSchema($fieldNameToSchema, $classname);
106+
return new ObjectSchema($fieldNameToSchema, $classname, $construct);
107107
}
108108

109109
public function record(SchemaInterface $fieldSchema): RecordSchema

src/Schema/ObjectConstructorSchema.php

Lines changed: 0 additions & 105 deletions
This file was deleted.

src/Schema/ObjectSchema.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class ObjectSchema extends AbstractObjectSchema implements ObjectSchemaInt
1616
* @param array<mixed, mixed> $fieldToSchema
1717
* @param class-string $classname
1818
*/
19-
public function __construct(array $fieldToSchema, private string $classname = \stdClass::class)
19+
public function __construct(array $fieldToSchema, private string $classname = \stdClass::class, private bool $construct = false)
2020
{
2121
parent::__construct($fieldToSchema);
2222
}
@@ -26,20 +26,29 @@ public function __construct(array $fieldToSchema, private string $classname = \s
2626
*/
2727
protected function parseFields(array $input, Errors $childrenErrors): object
2828
{
29-
$object = new ($this->classname);
30-
29+
$fields = [];
3130
foreach ($this->getFieldToSchema() as $fieldName => $fieldSchema) {
3231
try {
3332
if ($this->skip($input, $fieldName)) {
3433
continue;
3534
}
3635

37-
$object->{$fieldName} = $fieldSchema->parse($input[$fieldName] ?? null);
36+
$fields[$fieldName] = $fieldSchema->parse($input[$fieldName] ?? null);
3837
} catch (ErrorsException $e) {
3938
$childrenErrors->add($e->errors, $fieldName);
4039
}
4140
}
4241

43-
return $object;
42+
if (!$this->construct) {
43+
$object = new ($this->classname);
44+
45+
foreach ($fields as $fieldName => $fieldValue) {
46+
$object->{$fieldName} = $fieldValue;
47+
}
48+
49+
return $object;
50+
}
51+
52+
return new ($this->classname)(...$fields);
4453
}
4554
}

tests/Unit/ParserTest.php

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,30 @@ enum BackedSuit: string
3333
case Spades = 'S';
3434
}
3535

36+
final class ObjectDemo implements \JsonSerializable
37+
{
38+
public string $field1;
39+
40+
public function jsonSerialize(): array
41+
{
42+
return [
43+
'field1' => $this->field1,
44+
];
45+
}
46+
}
47+
48+
final class ObjectConstructDemo implements \JsonSerializable
49+
{
50+
public function __construct(public string $field1) {}
51+
52+
public function jsonSerialize(): array
53+
{
54+
return [
55+
'field1' => $this->field1,
56+
];
57+
}
58+
}
59+
3660
/**
3761
* @covers \Chubbyphp\Parsing\Parser
3862
*
@@ -159,7 +183,7 @@ public function testLiteral(): void
159183
self::assertInstanceOf(LiteralSchema::class, $literalSchema);
160184
}
161185

162-
public function testObject(): void
186+
public function testObjectStdClass(): void
163187
{
164188
$p = new Parser();
165189

@@ -170,6 +194,44 @@ public function testObject(): void
170194
self::assertInstanceOf(ObjectSchema::class, $objectSchema);
171195
}
172196

197+
public function testObjectWithObject(): void
198+
{
199+
$p = new Parser();
200+
201+
$objectSchema = $p->object([
202+
'field' => $p->string(),
203+
], ObjectDemo::class, );
204+
205+
$classnameReflection = new \ReflectionProperty(ObjectSchema::class, 'classname');
206+
207+
self::assertSame(ObjectDemo::class, $classnameReflection->getValue($objectSchema));
208+
209+
$constructReflection = new \ReflectionProperty(ObjectSchema::class, 'construct');
210+
211+
self::assertFalse($constructReflection->getValue($objectSchema));
212+
213+
self::assertInstanceOf(ObjectSchema::class, $objectSchema);
214+
}
215+
216+
public function testObjectWithObjectConstruct(): void
217+
{
218+
$p = new Parser();
219+
220+
$objectSchema = $p->object([
221+
'field' => $p->string(),
222+
], ObjectConstructDemo::class, true);
223+
224+
$classnameReflection = new \ReflectionProperty(ObjectSchema::class, 'classname');
225+
226+
self::assertSame(ObjectConstructDemo::class, $classnameReflection->getValue($objectSchema));
227+
228+
$constructReflection = new \ReflectionProperty(ObjectSchema::class, 'construct');
229+
230+
self::assertTrue($constructReflection->getValue($objectSchema));
231+
232+
self::assertInstanceOf(ObjectSchema::class, $objectSchema);
233+
}
234+
173235
public function testRecord(): void
174236
{
175237
$p = new Parser();

0 commit comments

Comments
 (0)