Skip to content

Commit

Permalink
fix: handle iterable objects as iterable during normalization
Browse files Browse the repository at this point in the history
This changes the behavior of the normalizer regarding iterable objects,
like `ArrayObject`,  `\Ds\Collection` or any other collection.

Before, the properties of the object would be accessed like any other
"basic" object. Now, the object will be treated as any other iterable
value.
  • Loading branch information
romm committed Jun 6, 2024
1 parent 40e6fa3 commit 6ee7804
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 23 deletions.
36 changes: 17 additions & 19 deletions src/Normalizer/Transformer/RecursiveTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace CuyZ\Valinor\Normalizer\Transformer;

use ArrayObject;
use BackedEnum;
use Closure;
use CuyZ\Valinor\Definition\AttributeDefinition;
Expand All @@ -16,7 +15,6 @@
use CuyZ\Valinor\Type\Types\NativeClassType;
use DateTimeInterface;
use DateTimeZone;
use Generator;
use stdClass;
use UnitEnum;
use WeakMap;
Expand Down Expand Up @@ -99,7 +97,22 @@ private function defaultTransformer(mixed $value, WeakMap $references): mixed
return $value;
}

if (is_object($value) && ! $value instanceof Closure && ! $value instanceof Generator) {
if (is_iterable($value)) {
if (is_array($value)) {
return array_map(
fn (mixed $value) => $this->doTransform($value, $references),
$value
);
}

return (function () use ($value, $references) {
foreach ($value as $key => $item) {
yield $key => $this->doTransform($item, $references);
}
})();
}

if (is_object($value) && ! $value instanceof Closure) {
if ($value instanceof UnitEnum) {
return $value instanceof BackedEnum ? $value->value : $value->name;
}
Expand All @@ -112,7 +125,7 @@ private function defaultTransformer(mixed $value, WeakMap $references): mixed
return $value->getName();
}

if ($value::class === stdClass::class || $value instanceof ArrayObject) {
if ($value::class === stdClass::class) {
return array_map(
fn (mixed $value) => $this->doTransform($value, $references),
(array)$value
Expand All @@ -136,21 +149,6 @@ private function defaultTransformer(mixed $value, WeakMap $references): mixed
return $transformed;
}

if (is_iterable($value)) {
if (is_array($value)) {
return array_map(
fn (mixed $value) => $this->doTransform($value, $references),
$value
);
}

return (function () use ($value, $references) {
foreach ($value as $key => $item) {
yield $key => $this->doTransform($item, $references);
}
})();
}

throw new TypeUnhandledByNormalizer($value);
}

Expand Down
7 changes: 3 additions & 4 deletions tests/Integration/Normalizer/NormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,9 @@ public function getIterator(): Traversable
}
},
'expected array' => [
'foo' => 'foo',
'bar' => 'bar',
'baz' => 'baz',
],
'expected json' => '{"foo":"foo","bar":"bar"}',
'expected json' => '{"baz":"baz"}',
];

yield 'date with default transformer' => [
Expand Down Expand Up @@ -384,7 +383,7 @@ public function getIterator(): Traversable
'expected array' => 'value',
'expected json' => '"value"',
'transformers' => [
[fn (object $object) => 'value'],
[fn (IteratorAggregate $object) => 'value'],
],
];

Expand Down

0 comments on commit 6ee7804

Please sign in to comment.