Repository: CuyZ/Valinor (php)

Issue:
Transform empty iterable object to array instead EmptyObject
If I pass empty Generator to json normalizer, I have `{data: {}}` in response, but I expect to get `{data: []}`.  
Let's look at `\CuyZ\Valinor\Normalizer\Transformer\RecursiveTransformer::defaultTransformer`  
You make tranformation of generator and check - is it closed or not, if closed - you return empty object, but why?
```
        if (is_iterable($value)) {
            ...

            if (! $result->valid()) {
                return EmptyObject::get();
            }

            return $result;
        }
```

Empty generator at response is empty list, isn't it?  
How about to replace into
```
            if (! $result->valid()) {
                return [];
            }
```

Than response is as expected - just `{data: []}`.  

Btw, removing `JSON_FORCE_OBJECT` from constructor of `JsonNormalizer` doesn't resolve the issue.

Pull request:
fix: normalize empty iterable object as empty array in JSON
Fixes #589

Patch:
diff --git a/src/Normalizer/Formatter/JsonFormatter.php b/src/Normalizer/Formatter/JsonFormatter.php
index 6a543f1..54354d3 100644
--- a/src/Normalizer/Formatter/JsonFormatter.php
+++ b/src/Normalizer/Formatter/JsonFormatter.php
@@ -11,7 +11,6 @@ use Generator;
 use function array_is_list;
 use function assert;
 use function fwrite;
-use function is_array;
 use function is_bool;
 use function is_iterable;
 use function is_null;
@@ -60,11 +59,19 @@ final class JsonFormatter implements StreamFormatter
             // afterward, this leads to a JSON array being written, while it
             // should have been an object. This is a trade-off we accept,
             // considering most generators starting at 0 are actually lists.
-            $isList = ! ($this->jsonEncodingOptions & JSON_FORCE_OBJECT)
-                && (
-                    ($value instanceof Generator && $value->key() === 0)
-                    || (is_array($value) && array_is_list($value))
-                );
+            if ($this->jsonEncodingOptions & JSON_FORCE_OBJECT) {
+                $isList = false;
+            } elseif ($value instanceof Generator) {
+                if (! $value->valid()) {
+                    $this->write('[]');
+                    return;
+                }
+
+                $isList = $value->key() === 0;
+            } else {
+                /** @var array<mixed> $value At this point we know this is an array */
+                $isList = array_is_list($value);
+            }
 
             $isFirst = true;
 
diff --git a/src/Normalizer/Transformer/RecursiveTransformer.php b/src/Normalizer/Transformer/RecursiveTransformer.php
index e140e46..ca10ce3 100644
--- a/src/Normalizer/Transformer/RecursiveTransformer.php
+++ b/src/Normalizer/Transformer/RecursiveTransformer.php
@@ -109,17 +109,11 @@ final class RecursiveTransformer
                 );
             }
 
-            $result = (function () use ($value, $references) {
+            return (function () use ($value, $references) {
                 foreach ($value as $key => $item) {
                     yield $key => $this->doTransform($item, $references);
                 }
             })();
-
-            if (! $result->valid()) {
-                return EmptyObject::get();
-            }
-
-            return $result;
         }
 
         if (is_object($value) && ! $value instanceof Closure) {


Test patch:
diff --git a/tests/Integration/Normalizer/NormalizerTest.php b/tests/Integration/Normalizer/NormalizerTest.php
index 4959a69..b2d0da7 100644
--- a/tests/Integration/Normalizer/NormalizerTest.php
+++ b/tests/Integration/Normalizer/NormalizerTest.php
@@ -743,7 +743,7 @@ final class NormalizerTest extends IntegrationTestCase
         yield 'ArrayObject with no property' => [
             'input' => new ArrayObject(),
             'expected array' => [],
-            'expected_json' => '{}',
+            'expected_json' => '[]',
         ];
 
         yield 'iterable class with no property' => [
@@ -757,7 +757,7 @@ final class NormalizerTest extends IntegrationTestCase
                 }
             },
             'expected array' => [],
-            'expected_json' => '{}',
+            'expected_json' => '[]',
         ];
 
         yield 'nested array with JSON_PRETTY_PRINT option' => [