Skip to content

Commit 11f9327

Browse files
committed
refactor(mapper): clean up dto caster and serializer
1 parent 9e0a10d commit 11f9327

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

packages/mapper/src/Casters/DtoCaster.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ public function __construct(
1919
public function cast(mixed $input): mixed
2020
{
2121
if (is_string($input) && Json\is_valid($input)) {
22-
return $this->deserializeRecursively(Json\decode($input));
22+
return $this->deserialize(Json\decode($input));
2323
}
2424

2525
if (is_array($input)) {
26-
return $this->deserializeRecursively($input);
26+
return $this->deserialize($input);
2727
}
2828

2929
if (is_string($input)) {
@@ -33,22 +33,19 @@ public function cast(mixed $input): mixed
3333
return $input;
3434
}
3535

36-
private function deserializeRecursively(mixed $input): mixed
36+
private function deserialize(mixed $input): mixed
3737
{
3838
if (is_array($input) && isset($input['type'], $input['data'])) {
3939
$class = Arr\find_key(
4040
array: $this->mapperConfig->serializationMap,
4141
value: $input['type'],
4242
) ?: $input['type'];
4343

44-
return map($this->deserializeRecursively($input['data']))->to($class);
44+
return map($this->deserialize($input['data']))->to($class);
4545
}
4646

4747
if (is_array($input)) {
48-
return array_map(
49-
fn (mixed $value) => $this->deserializeRecursively($value),
50-
$input,
51-
);
48+
return array_map(fn (mixed $value) => $this->deserialize($value), $input);
5249
}
5350

5451
return $input;

packages/mapper/src/Serializers/DtoSerializer.php

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
namespace Tempest\Mapper\Serializers;
44

5+
use BackedEnum;
6+
use JsonSerializable;
57
use Tempest\Mapper\Exceptions\ValueCouldNotBeSerialized;
68
use Tempest\Mapper\MapperConfig;
79
use Tempest\Mapper\Serializer;
10+
use Tempest\Reflection\ClassReflector;
11+
use Tempest\Reflection\PropertyReflector;
12+
use Tempest\Support\Arr;
813
use Tempest\Support\Json;
9-
10-
use function Tempest\map;
14+
use UnitEnum;
1115

1216
final readonly class DtoSerializer implements Serializer
1317
{
@@ -17,33 +21,33 @@ public function __construct(
1721

1822
public function serialize(mixed $input): array|string
1923
{
24+
// Support top-level arrays
2025
if (is_array($input)) {
21-
// Handle top-level arrays
22-
return Json\encode($this->wrapWithTypeInfo($input));
26+
return Json\encode($this->serializeWithType($input));
2327
}
2428

2529
if (! is_object($input)) {
2630
throw new ValueCouldNotBeSerialized('object or array');
2731
}
2832

29-
return Json\encode($this->wrapWithTypeInfo($input));
33+
return Json\encode($this->serializeWithType($input));
3034
}
3135

32-
private function wrapWithTypeInfo(mixed $input): mixed
36+
private function serializeWithType(mixed $input): mixed
3337
{
34-
if ($input instanceof \BackedEnum) {
38+
if ($input instanceof BackedEnum) {
3539
return $input->value;
3640
}
3741

38-
if ($input instanceof \UnitEnum) {
42+
if ($input instanceof UnitEnum) {
3943
return $input->name;
4044
}
4145

4246
if (is_object($input)) {
4347
$data = $this->extractObjectData($input);
4448

4549
foreach ($data as $key => $value) {
46-
$data[$key] = $this->wrapWithTypeInfo($value);
50+
$data[$key] = $this->serializeWithType($value);
4751
}
4852

4953
$type = $this->mapperConfig->serializationMap[get_class($input)] ?? get_class($input);
@@ -55,25 +59,21 @@ private function wrapWithTypeInfo(mixed $input): mixed
5559
}
5660

5761
if (is_array($input)) {
58-
return array_map([$this, 'wrapWithTypeInfo'], $input);
62+
return Arr\map_iterable($input, $this->serializeWithType(...));
5963
}
6064

6165
return $input;
6266
}
6367

6468
private function extractObjectData(object $input): array
6569
{
66-
if ($input instanceof \JsonSerializable) {
70+
if ($input instanceof JsonSerializable) {
6771
return $input->jsonSerialize();
6872
}
6973

70-
$data = [];
71-
$class = new \ReflectionClass($input);
72-
73-
foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
74-
$data[$property->getName()] = $property->getValue($input);
75-
}
76-
77-
return $data;
74+
return Arr\map_with_keys(
75+
array: new ClassReflector($input)->getPublicProperties(),
76+
map: fn (PropertyReflector $property) => yield $property->getName() => $property->getValue($input),
77+
);
7878
}
7979
}

0 commit comments

Comments
 (0)