Skip to content

Commit

Permalink
misc: improve mapping performance for nullable union type
Browse files Browse the repository at this point in the history
This adds a check within the loop for union type mapping, which will
skip `NullType` as it was already handled in `CasterProxyNodeBuilder`.

This greatly improves performance as it removes a useless call to the
whole node building process.
  • Loading branch information
NanoSector authored Apr 12, 2024
1 parent 1278392 commit 6fad94a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Mapper/Tree/Builder/UnionNodeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use CuyZ\Valinor\Type\ScalarType;
use CuyZ\Valinor\Type\StringType;
use CuyZ\Valinor\Type\Types\InterfaceType;
use CuyZ\Valinor\Type\Types\NullType;
use CuyZ\Valinor\Type\Types\ShapedArrayType;
use CuyZ\Valinor\Type\Types\UnionType;

Expand All @@ -38,6 +39,16 @@ public function build(Shell $shell, RootNodeBuilder $rootBuilder): TreeNode
$all = [];

foreach ($type->types() as $subType) {
// Performance optimisation: a `NullType` only accepts a `null`
// value, in which case the `CasterProxyNodeBuilder` would have
// handled it already. We can safely skip it here.
//
// @infection-ignore-all / This is a performance optimisation, so we
// cannot easily test this behavior.
if ($subType instanceof NullType) {
continue;
}

$node = $rootBuilder->build($shell->withType($subType));

if (! $node->isValid()) {
Expand Down
6 changes: 6 additions & 0 deletions tests/Integration/Mapping/UnionMappingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ public function test_union_mapping_works_properly_with_flexible_casting_enabled(

public static function union_mapping_works_properly_data_provider(): iterable
{
yield 'nullable scalar' => [
'type' => 'string|null',
'source' => null,
'assertion' => fn (mixed $result) => self::assertNull($result),
];

yield 'string or list of string, with string' => [
'type' => 'string|list<string>',
'source' => 'foo',
Expand Down

0 comments on commit 6fad94a

Please sign in to comment.