Skip to content

Commit 431ab3f

Browse files
committed
feat(mapper): handle mixed
1 parent f4cb9a2 commit 431ab3f

File tree

6 files changed

+85
-1
lines changed

6 files changed

+85
-1
lines changed

packages/mapper/src/Casters/ArrayToObjectCollectionCaster.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public function cast(mixed $input): mixed
2323

2424
$caster = match (true) {
2525
$iterableType->isEnum() => new EnumCaster($iterableType->getName()),
26+
$iterableType->getName() === 'mixed' => new MixedCaster(),
2627
$iterableType->isBuiltIn() => $this->casterFactory->forType($iterableType),
2728
default => new ObjectCaster($iterableType),
2829
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Mapper\Casters;
6+
7+
use Tempest\Mapper\Caster;
8+
9+
class MixedCaster implements Caster
10+
{
11+
public function cast(mixed $input): mixed
12+
{
13+
return $input;
14+
}
15+
}

packages/reflection/src/TypeReflector.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,13 @@ public function accepts(mixed $input): bool
8181
return true;
8282
}
8383

84+
if ($this->cleanDefinition === 'mixed') {
85+
return true;
86+
}
87+
8488
if ($this->isBuiltIn()) {
8589
return match ($this->cleanDefinition) {
8690
'false' => $input === false,
87-
'mixed' => true,
8891
'never' => false,
8992
'true' => $input === true,
9093
'void' => false,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Tempest\Integration\Mapper\Fixtures;
6+
7+
class ObjectWithMixedArray
8+
{
9+
/** @var mixed[] */
10+
public array $items;
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Tempest\Integration\Mapper\Fixtures;
6+
7+
class ObjectWithStringOrMixedArray
8+
{
9+
/** @var string|mixed[] */
10+
public string|array $items;
11+
}

tests/Integration/Mapper/Mappers/ArrayToObjectMapperTestCase.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithDoubleStringCaster;
1616
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithEnum;
1717
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithMagicGetter;
18+
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithMixedArray;
1819
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithMyObject;
20+
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithStringOrMixedArray;
1921
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithStringOrObjectUnion;
2022
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithStringsArray;
2123
use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithUnionArray;
@@ -231,6 +233,47 @@ public function test_map_union_string_or_object_with_object(): void
231233
$this->assertSame('1', $object->item->a);
232234
$this->assertSame('2', $object->item->b);
233235
}
236+
237+
public function test_map_array_with_mixed_array_property(): void
238+
{
239+
$object = map(['items' => ['a', 1, 2.5, true, null, ['key' => 'value']]])->to(ObjectWithMixedArray::class);
240+
241+
$this->assertSame(
242+
[
243+
'a',
244+
1,
245+
2.5,
246+
true,
247+
null,
248+
['key' => 'value'],
249+
],
250+
$object->items,
251+
);
252+
}
253+
254+
public function test_map_union_string_or_mixed_array_with_string(): void
255+
{
256+
$object = map(['items' => 'string'])->to(ObjectWithStringOrMixedArray::class);
257+
258+
$this->assertIsString($object->items);
259+
$this->assertSame('string', $object->items);
260+
}
261+
262+
public function test_map_union_string_or_mixed_array_with_array(): void
263+
{
264+
$object = map(['items' => ['a', 1, true, ['b' => 2]]])->to(ObjectWithStringOrMixedArray::class);
265+
266+
$this->assertIsArray($object->items);
267+
$this->assertSame(
268+
[
269+
'a',
270+
1,
271+
true,
272+
['b' => 2],
273+
],
274+
$object->items,
275+
);
276+
}
234277
}
235278

236279
final class ObjectWithArrayEnumProperty

0 commit comments

Comments
 (0)