Skip to content

Commit

Permalink
datamapper allows null
Browse files Browse the repository at this point in the history
  • Loading branch information
tenmajkl committed Jun 23, 2023
1 parent e48e313 commit 74c88be
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
27 changes: 17 additions & 10 deletions src/Lemon/DataMapper/DataMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Lemon\Support\Types\Maybe;
use Lemon\Support\Types\Nothing;
use ReflectionType;

class DataMapper
{
Expand All @@ -21,11 +22,8 @@ public static function mapTo(array $data, string $class): ?object
$reflection = new \ReflectionClass($class);
$params = [];
foreach ($reflection->getConstructor()->getParameters() as $property) {
if (!isset($data[$property->getName()])) {
return null;
}
$item = $data[$property->getName()];
$value = static::typeCheck($item, (string) $property->getType());
$item = $data[$property->getName()] ?? null;
$value = static::typeCheck($item, $property->getType());
if ($value instanceof Nothing) {
return null;
}
Expand All @@ -36,17 +34,26 @@ public static function mapTo(array $data, string $class): ?object
return new $class(...$params);
}

public static function typeCheck(mixed $value, string $type): Maybe
public static function typeCheck(mixed $value, ReflectionType $type): Maybe
{
if (class_exists($type)) {
$type_name = trim((string) $type, '?');
if (class_exists($type_name)) {
if ($type->allowsNull() && $value === null) {
return Maybe::just(null);
}

if (!is_array($value)) {
return Maybe::nothing();
}
}

return ($v = static::mapTo($value, $type_name)) === null ? Maybe::nothing() : Maybe::just($v);
}

return ($v = static::mapTo($value, $type)) === null ? Maybe::nothing() : Maybe::just($v);
if (!$type->allowsNull() && $value === null) {
return Maybe::nothing();
}

$ok = @settype($value, $type);
$ok = @settype($value, $type_name);

return $ok ? Maybe::just($value) : Maybe::nothing();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Lemon/Kernel/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final class Application extends Container
/**
* Current Lemon version.
*/
public const VERSION = '3.16.0';
public const VERSION = '3.16.1';

/**
* Default units with aliases.
Expand Down
17 changes: 17 additions & 0 deletions tests/DataMapper/DataMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ public function testMapping(): void

$this->assertThat(DataMapper::mapTo($data, TestArrayObject::class), $this->equalTo(new TestArrayObject(['bar', 'baz'])));
}

public function testNullable()
{
$data = [
'foo' => null,
];

$this->assertThat(DataMapper::mapTo($data, TestNullableObject::class), $this->equalTo(new TestNullableObject(null)));
}
}

class TestObject
Expand Down Expand Up @@ -97,3 +106,11 @@ public function __construct(
) {
}
}

class TestNullableObject
{
public function __construct(
public readonly ?TestObject $foo,
) {
}
}

0 comments on commit 74c88be

Please sign in to comment.