Skip to content

Commit 269bfcb

Browse files
authored
feat(mapper): ObjectToArrayMapper use Caster::serialize to serialize the property value (#947)
1 parent 0fe0df9 commit 269bfcb

16 files changed

+94
-24
lines changed

src/Tempest/Mapper/src/Casters/ArrayCaster.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Tempest\Mapper\Casters;
46

57
use Tempest\Mapper\Caster;
@@ -24,4 +26,4 @@ public function serialize(mixed $input): string
2426

2527
return json_encode($input);
2628
}
27-
}
29+
}

src/Tempest/Mapper/src/Exceptions/CannotSerializeValue.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Tempest\Mapper\Exceptions;
46

57
use Exception;
@@ -10,4 +12,4 @@ public function __construct(string $expectedType)
1012
{
1113
parent::__construct('Could not serialize value to ' . $expectedType);
1214
}
13-
}
15+
}

src/Tempest/Mapper/src/Mappers/JsonToArrayMapper.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace Tempest\Mapper\Mappers;
66

77
use Tempest\Mapper\Mapper;
8-
use Tempest\Mapper\MapTo;
98

109
final readonly class JsonToArrayMapper implements Mapper
1110
{

src/Tempest/Mapper/src/Mappers/JsonToObjectMapper.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace Tempest\Mapper\Mappers;
66

77
use Tempest\Mapper\Mapper;
8-
use Tempest\Mapper\MapTo;
98
use Tempest\Reflection\ClassReflector;
109
use Throwable;
1110
use function Tempest\map;

src/Tempest/Mapper/src/Mappers/ObjectToArrayMapper.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@
66

77
use JsonSerializable;
88
use ReflectionException;
9+
use Tempest\Mapper\Casters\CasterFactory;
910
use Tempest\Mapper\Mapper;
10-
use Tempest\Mapper\MapTo;
1111
use Tempest\Mapper\MapTo as MapToAttribute;
1212
use Tempest\Reflection\ClassReflector;
1313
use Tempest\Reflection\PropertyReflector;
1414
use function Tempest\Support\arr;
1515

1616
final readonly class ObjectToArrayMapper implements Mapper
1717
{
18+
public function __construct(
19+
private CasterFactory $casterFactory,
20+
) {
21+
}
22+
1823
public function canMap(mixed $from, mixed $to): bool
1924
{
2025
return false;
@@ -28,8 +33,8 @@ public function map(mixed $from, mixed $to): array
2833
foreach ($properties as $propertyName => $propertyValue) {
2934
try {
3035
$property = PropertyReflector::fromParts(class: $from, name: $propertyName);
31-
3236
$propertyName = $this->resolvePropertyName($property);
37+
$propertyValue = $this->resolvePropertyValue($property, $propertyValue);
3338

3439
$mappedProperties[$propertyName] = $propertyValue;
3540
} catch (ReflectionException) {
@@ -40,6 +45,13 @@ public function map(mixed $from, mixed $to): array
4045
return $mappedProperties;
4146
}
4247

48+
private function resolvePropertyValue(PropertyReflector $property, mixed $currentPropertyValue): mixed
49+
{
50+
$caster = $this->casterFactory->forProperty($property);
51+
52+
return $caster?->serialize($currentPropertyValue) ?? $currentPropertyValue;
53+
}
54+
4355
/**
4456
* @return array<string, mixed> The properties name and value
4557
*/

src/Tempest/Mapper/src/Mappers/ObjectToJsonMapper.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace Tempest\Mapper\Mappers;
66

77
use Tempest\Mapper\Mapper;
8-
use Tempest\Mapper\MapTo;
98
use function Tempest\map;
109

1110
final readonly class ObjectToJsonMapper implements Mapper

src/Tempest/Mapper/src/ObjectFactory.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ final class ObjectFactory
2626
public function __construct(
2727
private readonly MapperConfig $config,
2828
private readonly Container $container,
29-
) {}
29+
) {
30+
}
3031

3132
/**
3233
* @template T of object
@@ -87,11 +88,14 @@ public function toArray(): array
8788
{
8889
if (is_object($this->from)) {
8990
return $this->with(ObjectToArrayMapper::class);
90-
} elseif (is_array($this->from)) {
91+
}
92+
if (is_array($this->from)) {
9193
return $this->from;
92-
} elseif (is_string($this->from) && json_validate($this->from)) {
94+
}
95+
if (is_string($this->from) && json_validate($this->from)) {
9396
return $this->with(JsonToArrayMapper::class);
94-
} else {
97+
}
98+
else {
9599
throw new CannotMapDataException($this->from, 'array');
96100
}
97101
}
@@ -100,9 +104,11 @@ public function toJson(): string
100104
{
101105
if (is_object($this->from)) {
102106
return $this->with(ObjectToJsonMapper::class);
103-
} elseif (is_array($this->from)) {
107+
}
108+
if (is_array($this->from)) {
104109
return $this->with(ArrayToJsonMapper::class);
105-
} else {
110+
}
111+
else {
106112
throw new CannotMapDataException($this->from, 'json');
107113
}
108114
}
@@ -158,8 +164,7 @@ private function mapObject(
158164
mixed $from,
159165
mixed $to,
160166
bool $isCollection,
161-
): mixed
162-
{
167+
): mixed {
163168
if ($isCollection && is_array($from)) {
164169
return array_map(
165170
fn (mixed $item) => $this->mapObject(
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Tempest\Integration\Mapper\Fixtures;
6+
7+
enum EnumToCast: string
8+
{
9+
case FOO = 'foo';
10+
case BAR = 'bar';
11+
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Tests\Tempest\Integration\Mapper\Fixtures;
46

57
final readonly class Name
68
{
79
public function __construct(
810
public string $first,
911
public string $last,
10-
) {}
11-
}
12+
) {
13+
}
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Tempest\Integration\Mapper\Fixtures;
6+
7+
use DateTimeImmutable;
8+
use Tempest\Validation\Rules\DateTimeFormat;
9+
10+
final readonly class ObjectThatShouldUseCasters
11+
{
12+
public function __construct(
13+
public string $name,
14+
#[DateTimeFormat('Y-m-d')]
15+
public DateTimeImmutable $date,
16+
public EnumToCast $enum,
17+
) {
18+
}
19+
}

0 commit comments

Comments
 (0)