Skip to content

Commit

Permalink
fix: Serialize empty "map" arrays as objects in JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
autaut03 committed Oct 30, 2023
1 parent 20f5111 commit 0de9eca
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace GoodPhp\Serialization\TypeAdapter\Primitive\BuiltIn;

use Exception;
use GoodPhp\Reflection\Type\PrimitiveType;
use GoodPhp\Reflection\Type\Type;
use GoodPhp\Serialization\Serializer;
use GoodPhp\Serialization\TypeAdapter\Exception\CollectionItemMappingException;
Expand All @@ -21,8 +22,18 @@ final class ArrayMapper
* @return array<mixed>
*/
#[MapTo(PrimitiveTypeAdapter::class)]
public function to(array $value, Type $type, Serializer $serializer): array
public function to(array $value, Type $type, Serializer $serializer): array|\stdClass
{
if ($value === []) {
// Make sure that map arrays are serialized as object. To do so, we'll return an stdClass instead of
// an array so the upper layer can serialize it as an object, not an empty array.
if ($type->arguments[0]->equals(PrimitiveType::string())) {
return new \stdClass();
}

return $value;
}

$itemAdapter = $serializer->adapter(PrimitiveTypeAdapter::class, $type->arguments[1]);

return MultipleMappingException::map(
Expand All @@ -45,6 +56,10 @@ public function to(array $value, Type $type, Serializer $serializer): array
#[MapFrom(PrimitiveTypeAdapter::class)]
public function from(array $value, Type $type, Serializer $serializer): array
{
if ($value === []) {
return $value;
}

$itemAdapter = $serializer->adapter(PrimitiveTypeAdapter::class, $type->arguments[1]);

return MultipleMappingException::map(
Expand Down
7 changes: 4 additions & 3 deletions tests/Integration/JsonSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,10 @@ public function serializesProvider(): Generator
123,
MissingValue::INSTANCE,
new NestedStub('flattened'),
new CarbonImmutable('2020-01-01 00:00:00')
new CarbonImmutable('2020-01-01 00:00:00'),
['Some key' => 'Some value']
),
'{"primitive":1,"nested":{"Field":"something"},"date":"2020-01-01T00:00:00.000000Z","optional":123,"nullable":123,"Field":"flattened","carbonImmutable":"2020-01-01T00:00:00.000000Z"}',
'{"primitive":1,"nested":{"Field":"something"},"date":"2020-01-01T00:00:00.000000Z","optional":123,"nullable":123,"Field":"flattened","carbonImmutable":"2020-01-01T00:00:00.000000Z","other":{"Some key":"Some value"}}',
];

yield 'ClassStub with empty optional and null nullable' => [
Expand All @@ -166,7 +167,7 @@ public function serializesProvider(): Generator
new NestedStub('flattened'),
new CarbonImmutable('2020-01-01 00:00:00')
),
'{"primitive":1,"nested":{"Field":"something"},"date":"2020-01-01T00:00:00.000000Z","nullable":null,"Field":"flattened","carbonImmutable":"2020-01-01T00:00:00.000000Z"}',
'{"primitive":1,"nested":{"Field":"something"},"date":"2020-01-01T00:00:00.000000Z","nullable":null,"Field":"flattened","carbonImmutable":"2020-01-01T00:00:00.000000Z","other":{}}',
];
}

Expand Down
2 changes: 2 additions & 0 deletions tests/Stubs/ClassStub.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public function __construct(
#[Flatten]
public NestedStub $flattened,
public readonly CarbonImmutable $carbonImmutable,
/** @var array<string, string> */
public readonly array $other = [],
)
{
}
Expand Down

0 comments on commit 0de9eca

Please sign in to comment.