Skip to content

Commit af4f528

Browse files
committed
Add config drivers
1 parent 1076389 commit af4f528

File tree

56 files changed

+1248
-360
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1248
-360
lines changed

composer.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"symfony/property-access": "^5.4|^6.0|^7.0",
3535
"symfony/stopwatch": "^5.4|^6.0|^7.0",
3636
"symfony/var-dumper": "^5.4|^6.0|^7.0",
37+
"symfony/yaml": "^5.4|^6.0|^7.0",
38+
"nette/neon": "^3.0",
3739
"type-lang/phpdoc": "^1.0",
3840
"type-lang/phpdoc-standard-tags": "^1.0"
3941
},
@@ -43,8 +45,11 @@
4345
}
4446
},
4547
"suggest": {
46-
"type-lang/phpdoc-standard-tags": "(^1.0) Required for DocBlockDriver mapping driver support",
47-
"justinrainbow/json-schema": "(^5.3|^6.0) Required for configuration drivers validation"
48+
"ext-json": "Required for JSON mapping configuration files",
49+
"nette/neon": "(^3.0) Required for NEON mapping configuration files",
50+
"symfony/yaml": "(^5.4|^6.0|^7.0) Required for YAML mapping configuration files",
51+
"type-lang/phpdoc-standard-tags": "(^1.0) Required for PhpDoc mapping configuration",
52+
"justinrainbow/json-schema": "(^5.3|^6.0) Required for file-based configuration validation"
4853
},
4954
"extra": {
5055
"branch-alias": {

resources/config.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"map": {
2525
"type": "object",
2626
"description": "List of values for discriminator map. Each key must contain a value for the configured field",
27+
"minProperties": 1,
2728
"patternProperties": {
2829
"^.+?$": {
2930
"type": "string",
@@ -61,6 +62,11 @@
6162
"description": "Specific property type",
6263
"minLength": 1
6364
},
65+
"write": {
66+
"type": "string",
67+
"description": "Specific property write type",
68+
"minLength": 1
69+
},
6470
"type_error_message": {
6571
"type": "string",
6672
"minLength": 1,

src/Mapping/Metadata/ClassMetadata.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata\DiscriminatorMetadata;
88
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata\PropertyMetadata;
9+
use TypeLang\Mapper\Runtime\Context;
10+
use TypeLang\Parser\Node\Stmt\NamedTypeNode;
11+
use TypeLang\Parser\Node\Stmt\Shape\FieldsListNode;
12+
use TypeLang\Parser\Node\Stmt\TypeStatement;
913

1014
/**
1115
* Represents an abstraction over general information about a class.
@@ -55,4 +59,36 @@ public function __construct(
5559
) {
5660
parent::__construct($createdAt);
5761
}
62+
63+
/**
64+
* Dynamically creates AST class representation.
65+
*
66+
* Required to print type information in exceptions.
67+
*
68+
* @codeCoverageIgnore
69+
*/
70+
public function getTypeStatement(Context $context, bool $read): TypeStatement
71+
{
72+
if (!$context->isDetailedTypes()) {
73+
return new NamedTypeNode($this->name);
74+
}
75+
76+
$fields = [];
77+
78+
foreach ($this->properties as $property) {
79+
$field = $property->getFieldNode($context, $read);
80+
81+
if ($field === null) {
82+
continue;
83+
}
84+
85+
$fields[] = $field;
86+
}
87+
88+
if ($fields === []) {
89+
return new NamedTypeNode($this->name);
90+
}
91+
92+
return new NamedTypeNode($this->name, fields: new FieldsListNode($fields));
93+
}
5894
}

src/Mapping/Metadata/ClassMetadata/DiscriminatorInfo.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
namespace TypeLang\Mapper\Mapping\Metadata\ClassMetadata;
66

7+
use TypeLang\Mapper\Mapping\Metadata\MetadataInfo;
8+
use TypeLang\Mapper\Mapping\Metadata\SourceInfo;
79
use TypeLang\Mapper\Mapping\Metadata\TypeInfo;
810

9-
final class DiscriminatorInfo
11+
final class DiscriminatorInfo extends MetadataInfo
1012
{
1113
public function __construct(
1214
/**
@@ -18,5 +20,8 @@ public function __construct(
1820
*/
1921
public array $map,
2022
public ?TypeInfo $default = null,
21-
) {}
23+
?SourceInfo $source = null,
24+
) {
25+
parent::__construct($source);
26+
}
2227
}

src/Mapping/Metadata/ClassMetadata/PropertyInfo.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66

77
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata\PropertyMetadata\DefaultValueInfo;
88
use TypeLang\Mapper\Mapping\Metadata\ConditionInfo;
9+
use TypeLang\Mapper\Mapping\Metadata\MetadataInfo;
10+
use TypeLang\Mapper\Mapping\Metadata\SourceInfo;
911
use TypeLang\Mapper\Mapping\Metadata\TypeInfo;
1012

11-
final class PropertyInfo
13+
final class PropertyInfo extends MetadataInfo
1214
{
1315
/**
1416
* @var non-empty-string
@@ -41,8 +43,11 @@ public function __construct(
4143
* @var non-empty-string
4244
*/
4345
public readonly string $name,
46+
?SourceInfo $source = null,
4447
) {
4548
$this->alias = $name;
4649
$this->read = $this->write = new TypeInfo('mixed');
50+
51+
parent::__construct($source);
4752
}
4853
}

src/Mapping/Metadata/ClassMetadata/PropertyMetadata.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
use TypeLang\Mapper\Mapping\Metadata\ConditionMetadata;
99
use TypeLang\Mapper\Mapping\Metadata\Metadata;
1010
use TypeLang\Mapper\Mapping\Metadata\TypeMetadata;
11+
use TypeLang\Mapper\Runtime\Context;
12+
use TypeLang\Parser\Node\Stmt\NamedTypeNode;
13+
use TypeLang\Parser\Node\Stmt\Shape\NamedFieldNode;
14+
use TypeLang\Parser\Node\Stmt\TypeStatement;
1115

1216
final class PropertyMetadata extends Metadata
1317
{
@@ -61,4 +65,44 @@ public function __construct(
6165
) {
6266
parent::__construct($createdAt);
6367
}
68+
69+
/**
70+
* Dynamically creates AST type representation.
71+
*
72+
* @codeCoverageIgnore
73+
*/
74+
public function getTypeStatement(Context $context, bool $read): TypeStatement
75+
{
76+
$info = $read ? $this->read : $this->write;
77+
78+
$statement = clone $info->statement;
79+
80+
if ($context->isDetailedTypes() || !$statement instanceof NamedTypeNode) {
81+
return $statement;
82+
}
83+
84+
return new NamedTypeNode($statement->name);
85+
}
86+
87+
/**
88+
* Dynamically creates AST field representation.
89+
*
90+
* @codeCoverageIgnore
91+
*/
92+
public function getFieldNode(Context $context, bool $read): NamedFieldNode
93+
{
94+
$statement = $this->getTypeStatement($context, $read);
95+
96+
$name = $this->name;
97+
98+
if ($context->isDenormalization()) {
99+
$name = $this->alias;
100+
}
101+
102+
return new NamedFieldNode(
103+
key: $name,
104+
of: $statement,
105+
optional: $this->default !== null,
106+
);
107+
}
64108
}

src/Mapping/Metadata/ClassMetadata/PropertyMetadata/DefaultValueInfo.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44

55
namespace TypeLang\Mapper\Mapping\Metadata\ClassMetadata\PropertyMetadata;
66

7-
final class DefaultValueInfo
7+
use TypeLang\Mapper\Mapping\Metadata\MetadataInfo;
8+
use TypeLang\Mapper\Mapping\Metadata\SourceInfo;
9+
10+
final class DefaultValueInfo extends MetadataInfo
811
{
912
public function __construct(
1013
public readonly mixed $value,
11-
) {}
14+
?SourceInfo $source = null,
15+
) {
16+
parent::__construct($source);
17+
}
1218
}

src/Mapping/Metadata/Condition/ExpressionConditionInfo.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace TypeLang\Mapper\Mapping\Metadata\Condition;
66

77
use TypeLang\Mapper\Mapping\Metadata\ConditionInfo;
8+
use TypeLang\Mapper\Mapping\Metadata\SourceInfo;
89

910
final class ExpressionConditionInfo extends ConditionInfo
1011
{
@@ -22,5 +23,8 @@ public function __construct(
2223
* @var non-empty-string
2324
*/
2425
public readonly string $context = self::DEFAULT_CONTEXT_VARIABLE_NAME,
25-
) {}
26+
?SourceInfo $source = null,
27+
) {
28+
parent::__construct($source);
29+
}
2630
}

src/Mapping/Metadata/ConditionInfo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
namespace TypeLang\Mapper\Mapping\Metadata;
66

7-
abstract class ConditionInfo {}
7+
abstract class ConditionInfo extends MetadataInfo {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\Mapper\Mapping\Metadata;
6+
7+
abstract class MetadataInfo
8+
{
9+
public function __construct(
10+
public ?SourceInfo $source = null,
11+
) {}
12+
}

0 commit comments

Comments
 (0)