Skip to content

Commit 7ff9b9f

Browse files
authored
Mapping null to nullable properties (#17)
1 parent 4db08a6 commit 7ff9b9f

File tree

5 files changed

+37
-0
lines changed

5 files changed

+37
-0
lines changed

src/Objects/ObjectMapper.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ private function castInMapperFunction(string $propertyName, DataTypeCollection $
149149
{
150150
if (\count($type->types) === 1) {
151151
$type = $type->types[0];
152+
153+
if ($type->isNullable) {
154+
return "{$propertyName} === null ? null : " . $this->castInMapperFunction($propertyName, new DataTypeCollection([$type->removeNullable()]), $bluePrint);
155+
}
156+
152157
if ($type->isNative()) {
153158
return match ($type->type) {
154159
'null' => 'null',
@@ -187,6 +192,10 @@ private function castInMapperFunction(string $propertyName, DataTypeCollection $
187192

188193
private function wrapDefault(string $value, string $arrayKey, mixed $defaultValue): string
189194
{
195+
if (\str_contains($value, '?')) {
196+
$value = "({$value})";
197+
}
198+
190199
return "(\\array_key_exists('{$arrayKey}', \$data) ? {$value} : " . \var_export($defaultValue, true) . ')';
191200
}
192201

src/Types/DataType.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,12 @@ public function isNative(): bool
4747
],
4848
);
4949
}
50+
51+
/**
52+
* returns a new instance of itself that is not nullable
53+
*/
54+
public function removeNullable(): self
55+
{
56+
return new self($this->type, false, $this->genericTypes);
57+
}
5058
}

tests/MapperTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public static function nativeValuesDataProvider(): Generator
6565
yield ['int', 5, 5];
6666
yield ['int', '8', 8];
6767
yield ['int', 8.3, 8];
68+
yield ['?int', null, null];
69+
yield ['int|string|null', null, null];
6870
yield ['int[]', [5, 8], [5, 8]];
6971
yield ['int[][][][][]', [[[[['5']]]]], [[[[[5]]]]]];
7072
yield ['array<int[][]>[][]', [[[[['0']]]]], [[[[[0]]]]]];
@@ -175,5 +177,17 @@ public static function objectValuesDataProvider(): Generator
175177
],
176178
$dto,
177179
];
180+
181+
// Null for nullable properties
182+
$dto = new UserDto('Joe');
183+
$dto->score = null;
184+
yield [
185+
UserDto::class,
186+
[
187+
'name' => 'Joe',
188+
'score' => null,
189+
],
190+
$dto,
191+
];
178192
}
179193
}

tests/Objects/ClassBluePrinterTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ public static function classBlueprintDataProvider(): Generator
5656
]),
5757
'default' => null,
5858
],
59+
'score' => [
60+
'type' => new DataTypeCollection([
61+
new DataType('int', true)
62+
]),
63+
],
5964
],
6065
];
6166
}

tests/_Mocks/UserDto.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class UserDto
1313
/** @var array<self> */
1414
public array $friends = [];
1515
public ?SuitEnum $favoriteSuit = null;
16+
public ?int $score;
1617

1718
public function __construct(string $name)
1819
{

0 commit comments

Comments
 (0)