Skip to content

Commit 33a251d

Browse files
committed
Add getBackedEnumOrNull method to Arr class for enum retrieval with validation
1 parent 638f3fc commit 33a251d

File tree

2 files changed

+97
-4
lines changed

2 files changed

+97
-4
lines changed

src/Support/Arr.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace Nuxtifyts\PhpDto\Support;
44

5+
use BackedEnum;
6+
use InvalidArgumentException;
7+
58
final readonly class Arr
69
{
710
/**
@@ -89,6 +92,40 @@ public static function getBoolean(array $array, string $key, bool $default = fal
8992
return self::getBooleanOrNull($array, $key) ?? $default;
9093
}
9194

95+
/**
96+
* @template T of BackedEnum
97+
*
98+
* @param array<array-key, mixed> $array
99+
* @param class-string<T> $enumClass
100+
* @param ?T $default
101+
*
102+
* @return ?T
103+
*/
104+
public static function getBackedEnumOrNull(
105+
array $array,
106+
string $key,
107+
string $enumClass,
108+
?BackedEnum $default = null
109+
): ?BackedEnum {
110+
$value = $array[$key] ?? null;
111+
112+
if ($value instanceof $enumClass) {
113+
return $value;
114+
} else if (
115+
(is_string($value) || is_integer($value))
116+
&& $resolvedValue = $enumClass::tryFrom($value)
117+
) {
118+
return $resolvedValue;
119+
}
120+
121+
return is_null($default)
122+
? null
123+
: ($default instanceof $enumClass
124+
? $default
125+
: throw new InvalidArgumentException('Default value must be an instance of ' . $enumClass)
126+
);
127+
}
128+
92129
/**
93130
* @param array<array-key, mixed> $array
94131
* @param class-string<object> $classString

tests/Unit/Support/ArrTest.php

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22

33
namespace Nuxtifyts\PhpDto\Tests\Unit\Support;
44

5-
use Nuxtifyts\PhpDto\Serializers\BackedEnumSerializer;
6-
use Nuxtifyts\PhpDto\Serializers\ScalarTypeSerializer;
7-
use Nuxtifyts\PhpDto\Serializers\Serializer;
5+
use InvalidArgumentException;
86
use Nuxtifyts\PhpDto\Support\Arr;
7+
use PHPUnit\Framework\Attributes\Test;
98
use Nuxtifyts\PhpDto\Tests\Unit\UnitCase;
9+
use PHPUnit\Framework\Attributes\UsesClass;
10+
use Nuxtifyts\PhpDto\Serializers\Serializer;
1011
use PHPUnit\Framework\Attributes\CoversClass;
1112
use PHPUnit\Framework\Attributes\DataProvider;
12-
use PHPUnit\Framework\Attributes\Test;
13+
use Nuxtifyts\PhpDto\Serializers\BackedEnumSerializer;
14+
use Nuxtifyts\PhpDto\Serializers\ScalarTypeSerializer;
15+
use Nuxtifyts\PhpDto\Tests\Dummies\Enums\YesNoBackedEnum;
16+
use Nuxtifyts\PhpDto\Tests\Dummies\Enums\ColorsBackedEnum;
1317

1418
#[CoversClass(Arr::class)]
19+
#[UsesClass(YesNoBackedEnum::class)]
20+
#[UsesClass(ColorsBackedEnum::class)]
1521
final class ArrTest extends UnitCase
1622
{
1723
/**
@@ -254,9 +260,59 @@ public static function get_arr_provider(): array
254260
],
255261
null,
256262
],
263+
'get backed enum or null, invalid value' => [
264+
'getBackedEnumOrNull',
265+
[
266+
'array' => ['key' => 'invalid'],
267+
'key' => 'key',
268+
'enumClass' => YesNoBackedEnum::class,
269+
],
270+
null
271+
],
272+
'get backed enum or null, invalid value default provided' => [
273+
'getBackedEnumOrNull',
274+
[
275+
'array' => ['key' => 'invalid'],
276+
'key' => 'key',
277+
'enumClass' => YesNoBackedEnum::class,
278+
'default' => YesNoBackedEnum::NO,
279+
],
280+
YesNoBackedEnum::NO
281+
],
282+
'get backed enum or null, valid backed enum value' => [
283+
'getBackedEnumOrNull',
284+
[
285+
'array' => ['key' => YesNoBackedEnum::YES],
286+
'key' => 'key',
287+
'enumClass' => YesNoBackedEnum::class,
288+
],
289+
YesNoBackedEnum::YES
290+
],
291+
'get backed enum or null, valid string value' => [
292+
'getBackedEnumOrNull',
293+
[
294+
'array' => ['key' => 'yes'],
295+
'key' => 'key',
296+
'enumClass' => YesNoBackedEnum::class,
297+
],
298+
YesNoBackedEnum::YES
299+
]
257300
];
258301
}
259302

303+
#[Test]
304+
public function get_backed_enum_or_null_will_throw_an_exception_if_default_value_is_invalid(): void
305+
{
306+
self::expectException(InvalidArgumentException::class);
307+
308+
Arr::getBackedEnumOrNull(
309+
['key' => 'invalid'],
310+
'key',
311+
YesNoBackedEnum::class,
312+
ColorsBackedEnum::RED
313+
);
314+
}
315+
260316
/**
261317
* @return array<string, mixed>
262318
*/

0 commit comments

Comments
 (0)