Skip to content

Commit

Permalink
feat: support mixed values
Browse files Browse the repository at this point in the history
  • Loading branch information
vuryss committed Jun 24, 2024
1 parent f6a7642 commit 5b36ef3
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/Denormalizer/MixedTypeDenormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Vuryss\Serializer\Denormalizer;

use Vuryss\Serializer\Denormalizer;
use Vuryss\Serializer\DenormalizerInterface;
use Vuryss\Serializer\Metadata\DataType;
use Vuryss\Serializer\Metadata\BuiltInType;
use Vuryss\Serializer\Path;

class MixedTypeDenormalizer implements DenormalizerInterface
{
public function denormalize(mixed $data, DataType $type, Denormalizer $denormalizer, Path $path): mixed
{
return $data;
}

public function supportsDenormalization(mixed $data, DataType $type): bool
{
return BuiltInType::MIXED === $type->type;
}
}
6 changes: 6 additions & 0 deletions src/Metadata/MetadataExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ private function resolveType(
);

if (null === $extractedTypes) {
$reflectionType = $reflectionProperty->getType();

if ($reflectionType instanceof \ReflectionNamedType && 'mixed' === $reflectionType->getName()) {
return [new DataType(BuiltInType::MIXED, attributes: $serializerContext->attributes)];
}

throw new MetadataExtractionException(
sprintf(
'Failed to extract types of property "%s" of class "%s"',
Expand Down
2 changes: 2 additions & 0 deletions src/Serializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Vuryss\Serializer\Denormalizer\DateTimeDenormalizer;
use Vuryss\Serializer\Denormalizer\EnumDenormalizer;
use Vuryss\Serializer\Denormalizer\InterfaceDenormalizer;
use Vuryss\Serializer\Denormalizer\MixedTypeDenormalizer;
use Vuryss\Serializer\Denormalizer\ObjectDenormalizer;
use Vuryss\Serializer\Exception\EncodingException;
use Vuryss\Serializer\Metadata\CachedMetadataExtractor;
Expand Down Expand Up @@ -63,6 +64,7 @@ public function __construct(
new DateTimeDenormalizer(),
new ObjectDenormalizer(),
new InterfaceDenormalizer(),
new MixedTypeDenormalizer(),
]
: $denormalizers;

Expand Down
10 changes: 10 additions & 0 deletions tests/Datasets/MixedValues.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Vuryss\Serializer\Tests\Datasets;

class MixedValues
{
public mixed $mixedValue;
}
18 changes: 18 additions & 0 deletions tests/Unit/DeserializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,21 @@

expect($string)->json()->toMatchArray(json_decode(Car::getJsonSerialized(), true));
});

test('Deserializing into mixed value field', function (mixed $expected, string $serialized) {
$serializer = new \Vuryss\Serializer\Serializer();
$object = $serializer->deserialize($serialized, \Vuryss\Serializer\Tests\Datasets\MixedValues::class);

expect($object)
->toBeInstanceOf(\Vuryss\Serializer\Tests\Datasets\MixedValues::class)
->and($object->mixedValue)
->toBe($expected);
})->with([
'int' => [654, '{"mixedValue":654}'],
'float' => [654.321, '{"mixedValue":654.321}'],
'string' => ['string', '{"mixedValue":"string"}'],
'bool' => [true, '{"mixedValue":true}'],
'null' => [null, '{"mixedValue":null}'],
'array' => [['array', 'of', 'values'], '{"mixedValue":["array","of","values"]}'],
'object' => [['key' => 'value'], '{"mixedValue":{"key":"value"}}'],
]);
25 changes: 25 additions & 0 deletions tests/Unit/SerializerTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?php

/**
* @noinspection PhpUnhandledExceptionInspection
*/

declare(strict_types=1);

use Vuryss\Serializer\Serializer;
use Vuryss\Serializer\Tests\Datasets\ClassWithNestedClass;
Expand Down Expand Up @@ -77,3 +82,23 @@

expect($serialized)->toBe('[{"firstName":"John","lastName":"Doe","age":25,"isStudent":true},{"firstName":"Maria","lastName":"Valentina","age":36,"isStudent":false}]');
});

test('Serializing of mixed values', function ($value, $serialized) {
$serializer = new Serializer();

$mixedValueObject = new \Vuryss\Serializer\Tests\Datasets\MixedValues();
$mixedValueObject->mixedValue = 123;

$serialized = $serializer->serialize($mixedValueObject);

expect($serialized)->toBe('{"mixedValue":123}');
})->with([
'int' => [123, '{"mixedValue":123}'],
'float' => [123.45, '{"mixedValue":123.45}'],
'string' => ['string', '{"mixedValue":"string"}'],
'bool' => [true, '{"mixedValue":true}'],
'null' => [null, '{"mixedValue":null}'],
'array' => [[1, 2, 3], '{"mixedValue":[1,2,3]}'],
'object' => [new stdClass(), '{"mixedValue":{}}'],
'object with properties' => [(object) ['property' => 'value'], '{"mixedValue":{"property":"value"}}'],
]);

0 comments on commit 5b36ef3

Please sign in to comment.