Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions bench/src/Serializers/TypeLangAttributesBench.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
use PhpBench\Attributes\Warmup;
use TypeLang\Mapper\Bench\Stub\ExampleRequestDTO;
use TypeLang\Mapper\Mapper;
use TypeLang\Mapper\Mapping\Driver\AttributeDriver;
use TypeLang\Mapper\Mapping\Driver\Psr16CachedDriver;
use TypeLang\Mapper\Mapping\Driver\ReflectionDriver;
use TypeLang\Mapper\Mapping\Provider\Psr16CacheProvider;
use TypeLang\Mapper\Mapping\Reader\AttributeReader;
use TypeLang\Mapper\Platform\StandardPlatform;

#[Revs(30), Warmup(3), Iterations(5), BeforeMethods('prepare')]
Expand All @@ -25,22 +24,20 @@ public function prepare(): void
{
parent::prepare();

$driver = new AttributeDriver(
delegate: new ReflectionDriver(),
);
$driver = new AttributeReader();

$this->cached = new Mapper(
platform: new StandardPlatform(
driver: new Psr16CachedDriver(
cache: $this->psr16,
meta: new Psr16CacheProvider(
psr16: $this->psr16,
delegate: $driver,
),
),
);

$this->raw = new Mapper(
platform: new StandardPlatform(
driver: $driver,
meta: $driver,
),
);
}
Expand Down
16 changes: 7 additions & 9 deletions bench/src/Serializers/TypeLangDocBlockBench.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
use PhpBench\Attributes\Warmup;
use TypeLang\Mapper\Bench\Stub\ExampleRequestDTO;
use TypeLang\Mapper\Mapper;
use TypeLang\Mapper\Mapping\Driver\DocBlockDriver;
use TypeLang\Mapper\Mapping\Driver\Psr16CachedDriver;
use TypeLang\Mapper\Mapping\Driver\ReflectionDriver;
use TypeLang\Mapper\Mapping\Provider\Psr16CacheProvider;
use TypeLang\Mapper\Mapping\Reader\PhpDocReader;
use TypeLang\Mapper\Mapping\Reader\ReflectionReader;
use TypeLang\Mapper\Platform\StandardPlatform;

#[Revs(30), Warmup(3), Iterations(5), BeforeMethods('prepare')]
Expand All @@ -25,22 +25,20 @@ public function prepare(): void
{
parent::prepare();

$driver = new DocBlockDriver(
delegate: new ReflectionDriver(),
);
$driver = new PhpDocReader();

$this->cached = new Mapper(
platform: new StandardPlatform(
driver: new Psr16CachedDriver(
cache: $this->psr16,
meta: new Psr16CacheProvider(
psr16: $this->psr16,
delegate: $driver,
),
),
);

$this->raw = new Mapper(
platform: new StandardPlatform(
driver: $driver,
meta: $driver,
),
);
}
Expand Down
10 changes: 8 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"require": {
"php": "^8.1",
"psr/clock": "^1.0",
"psr/log": "^1.0|^2.0|^3.0",
"psr/simple-cache": "^1.0|^2.0|^3.0",
"type-lang/parser": "^1.4",
Expand All @@ -33,6 +34,8 @@
"symfony/property-access": "^5.4|^6.0|^7.0",
"symfony/stopwatch": "^5.4|^6.0|^7.0",
"symfony/var-dumper": "^5.4|^6.0|^7.0",
"symfony/yaml": "^5.4|^6.0|^7.0",
"nette/neon": "^3.0",
"type-lang/phpdoc": "^1.0",
"type-lang/phpdoc-standard-tags": "^1.0"
},
Expand All @@ -42,8 +45,11 @@
}
},
"suggest": {
"type-lang/phpdoc-standard-tags": "(^1.0) Required for DocBlockDriver mapping driver support",
"justinrainbow/json-schema": "(^5.3|^6.0) Required for configuration drivers validation"
"ext-json": "Required for JSON mapping configuration files",
"nette/neon": "(^3.0) Required for NEON mapping configuration files",
"symfony/yaml": "(^5.4|^6.0|^7.0) Required for YAML mapping configuration files",
"type-lang/phpdoc-standard-tags": "(^1.0) Required for PhpDoc mapping configuration",
"justinrainbow/json-schema": "(^5.3|^6.0) Required for file-based configuration validation"
},
"extra": {
"branch-alias": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function __construct(

$result = $mapper->normalize($value);

dd($result);
var_dump($result);
//
// array:1 [
// "items" => array:3 [
Expand Down
24 changes: 12 additions & 12 deletions example/01.normalization/08.object-output-normalization.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ public function __construct(

var_dump($result);
//
// object{
// items: array:3 [
// "key1" => object{
// value: "first"
// }
// "key2" => object{
// value: "second"
// }
// 0 => object{
// value: "third"
// }
// array:1 [
// "items" => array:3 [
// "key1" => array:1 [
// "value" => "first"
// ]
// "key2" => array:1 [
// "value" => "second"
// ]
// 0 => array:1 [
// "value" => "third"
// ]
// ]
// }
// ]
//
12 changes: 4 additions & 8 deletions example/02.errors/01.custom-type-printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,15 @@ public function __construct(
]
], ExampleDTO::class);
} catch (RuntimeException $e) {
// Before
var_dump($e->getMessage());
// - Type: "list<ExampleDTO>"
// - Message: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values

// Replace all "expected type" definition to PHP-supported printer
// instead of PrettyPrinter
$e->template->types = new \TypeLang\Printer\NativeTypePrinter();

// After
// Before: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values
// After: Passed value in "values" of {"values": 42} must be of type
// array, but 42 given at $.values[1].values
var_dump($e->getMessage());
// - Type: "array"
// - Message: Passed value in "values" of {"values": 42} must be of type
// array, but 42 given at $.values[1].values
}
12 changes: 4 additions & 8 deletions example/02.errors/02.extended-type-printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ public function __construct(
],
], ExampleDTO::class);
} catch (RuntimeException $e) {
// Before
var_dump($e->getMessage());
// - Type: "list<ExampleDTO>"
// - Message: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values

// Print all NamedTypeNode AST statements as "!!!MODIFIED!!!" string
$e->template->types = new class extends PrettyPrinter {
Expand All @@ -42,9 +38,9 @@ protected function printNamedTypeNode(NamedTypeNode $node): string
}
};

// After
// Before: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values
// After: Passed value in "values" of {"values": 42} must be of type
// !!!MODIFIED!!!, but 42 given at $.values[1].values
var_dump($e->getMessage());
// - Type: "!!!MODIFIED!!!"
// - Message: Passed value in "values" of {"values": 42} must be of type
// !!!MODIFIED!!!, but 42 given at $.values[1].values
}
29 changes: 11 additions & 18 deletions example/02.errors/03.custom-value-printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,37 +28,30 @@ public function __construct(
],
], ExampleDTO::class);
} catch (RuntimeException $e) {
// Before
var_dump($e->getMessage());
// - Value#1: "of {"values": 42}"
// - Value#2: "but 42 given"
// - Message: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values

// Print all values using PHP-compatible types
$e->template->values = new PHPValuePrinter();

// After#1
// Before: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values
// After#1: Passed value in string of stdClass must be of type
// list<ExampleDTO>, but int given at $.values[1].values
var_dump($e->getMessage());
// - Value#1: "of array"
// - Value#2: "but int given"
// - Message: Passed value in "values" of array must be of type
// list<ExampleDTO>, but int given at $.values[1].values


// In case of symfony/var-dumper is installed, we can use it
if (\Composer\InstalledVersions::isInstalled('symfony/var-dumper')) {
// Print all values using SymfonyValuePrinter
$e->template->values = new SymfonyValuePrinter();

// After#2
// Before: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values
// After#1: Passed value in string of stdClass must be of type
// list<ExampleDTO>, but int given at $.values[1].values
// After#2: Passed value in "values" of {#394
// +"values": 42
// } must be of type list<ExampleDTO>, but 42 given at $.values[1].values
var_dump($e->getMessage());
// - Value#1: "of array:1 [
// "values" => 42
// ]"
// - Value#2: "but 42 given"
// - Message: Passed value in "values" of array:1 [
// "values" => 42
// ] must be of type list<ExampleDTO>, but 42 given at $.values[1].values
}
}
11 changes: 5 additions & 6 deletions example/02.errors/04.custom-path-printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ public function __construct(
],
], ExampleDTO::class);
} catch (RuntimeException $e) {
// Before: "at $.values[1].values"
var_dump($e->getMessage());
// Passed value of field "values" must be of type list<ExampleDTO>,
// but 42 given at $.values[1].values

// Print full path using ">" delimiter
$e->template->paths = new class implements PathPrinterInterface {
Expand All @@ -41,8 +38,10 @@ public function print(PathInterface $path): string
}
};

// After: "at ExampleDTO > values > 1 > ExampleDTO > values"
// Before: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at $.values[1].values
// After: Passed value in "values" of {"values": 42} must be of type
// list<ExampleDTO>, but 42 given at ExampleDTO > values >
// 1 > ExampleDTO > values
var_dump($e->getMessage());
// Passed value of field "values" must be of type list<ExampleDTO>,
// but 42 given at ExampleDTO > values > 1 > ExampleDTO > values
}
19 changes: 15 additions & 4 deletions example/03.types/03.custom-type-template-arguments.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,30 @@ public function cast(mixed $value, Context $context): mixed
// ]
//

var_dump($mapper->normalize([], 'non-empty<string>'));
try {
var_dump($mapper->normalize([], 'non-empty<string>'));
} catch (\Throwable $e) {
echo $e->getMessage() . "\n";
}
//
// InvalidValueException: Passed value [] is invalid
//


var_dump($mapper->normalize('example', 'non-empty'));
try {
var_dump($mapper->normalize('example', 'non-empty'));
} catch (\Throwable $e) {
echo $e->getMessage() . "\n";
}
//
// MissingTemplateArgumentsException: Type "non-empty" expects at least 1
// template argument(s), but 0 were passed
//

var_dump($mapper->normalize('', 'non-empty<string>'));
try {
var_dump($mapper->normalize('', 'non-empty<string>'));
} catch (\Throwable $e) {
echo $e->getMessage() . "\n";
}
//
// InvalidValueException: Passed value "" is invalid
//
15 changes: 12 additions & 3 deletions example/03.types/04.custom-platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,22 @@ public function __construct(

$mapper = new Mapper(new SimplePlatform());

var_dump($mapper->normalize(new ExampleDTO()));
try {
var_dump($mapper->normalize(new ExampleDTO()));
} catch (\Throwable $e) {
echo $e->getMessage() . "\n";
}
//
// TypeRequiredException: Type "int" for property ExampleDTO::$value
// is not defined
//

var_dump($mapper->normalize([new ExampleDTO()], 'array<ExampleDTO>'));
try {
var_dump($mapper->normalize([new ExampleDTO()], 'array<ExampleDTO>'));
} catch (\Throwable $e) {
echo $e->getMessage() . "\n";
}
//
// ParseException: Template arguments not allowed in "array<ExampleDTO>" at column 6
// ParseException: Template arguments not allowed in "array<ExampleDTO>"
// at column 6
//
1 change: 0 additions & 1 deletion example/03.types/06.custom-type-psr-container.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use TypeLang\Mapper\Platform\DelegatePlatform;
use TypeLang\Mapper\Platform\StandardPlatform;
use TypeLang\Mapper\Runtime\Context;
use TypeLang\Mapper\Type\Builder\CallableTypeBuilder;
use TypeLang\Mapper\Type\Builder\PsrContainerTypeBuilder;
use TypeLang\Mapper\Type\TypeInterface;

Expand Down
38 changes: 38 additions & 0 deletions example/04.mapping-readers/01.reflection-mapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

use TypeLang\Mapper\Mapper;

require __DIR__ . '/../../vendor/autoload.php';

class ExampleDTO
{
public function __construct(
public readonly array $value = [],
) {}
}

// Create standard platform with REFLECTION READER
$platform = new \TypeLang\Mapper\Platform\StandardPlatform(
meta: new \TypeLang\Mapper\Mapping\Reader\ReflectionReader(),
);

$mapper = new Mapper($platform);

var_dump($mapper->denormalize([
'value' => ['string', 'string 2'],
], ExampleDTO::class));

//
// Because NATIVE type hint is "array" that infers to "array<array-key, mixed>"
//
// object(ExampleDTO)#345 (1) {
// ["value"] => array(2) {
// [0] => string(6) "string"
// [1] => string(8) "string 2"
// }
// }
//


Loading
Loading