Skip to content

Commit 9343c3f

Browse files
author
Michael Petri
committed
Added new named constructor to create enum from mixed
The current implementation of Enum requires to pass a valid enum value to class constructor. With this new named constructor we can just pass any value to enum and get an instance or unexpected value exception.
1 parent 616601d commit 9343c3f

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

src/Enum.php

+27-3
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,24 @@ public function __construct($value)
6161
$value = $value->getValue();
6262
}
6363

64-
if (!$this->isValid($value)) {
65-
throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class);
66-
}
64+
self::assertValidValue($value);
6765

6866
/** @psalm-var T */
6967
$this->value = $value;
7068
}
7169

70+
/**
71+
* @param mixed $value
72+
* @return static
73+
* @psalm-return static<T>
74+
*/
75+
public static function fromMixed($value): self
76+
{
77+
self::assertValidValue($value);
78+
79+
return new static($value);
80+
}
81+
7282
/**
7383
* @psalm-pure
7484
* @return mixed
@@ -175,13 +185,27 @@ public static function toArray()
175185
* @param $value
176186
* @psalm-param mixed $value
177187
* @psalm-pure
188+
* @psalm-assert-if-true T $value
178189
* @return bool
179190
*/
180191
public static function isValid($value)
181192
{
182193
return \in_array($value, static::toArray(), true);
183194
}
184195

196+
/**
197+
* Asserts valid enum value
198+
*
199+
* @psalm-pure
200+
* @psalm-assert T $value
201+
*/
202+
public static function assertValidValue($value): void
203+
{
204+
if (!self::isValid($value)) {
205+
throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class);
206+
}
207+
}
208+
185209
/**
186210
* Check if is valid enum key
187211
*

tests/EnumTest.php

+15
Original file line numberDiff line numberDiff line change
@@ -332,4 +332,19 @@ public function testEnumValuesInheritance()
332332
$inheritedEnumFixture = InheritedEnumFixture::VALUE();
333333
new EnumFixture($inheritedEnumFixture);
334334
}
335+
336+
/**
337+
* @dataProvider isValidProvider
338+
*/
339+
public function testAssertValidValue($value, $isValid): void
340+
{
341+
if (!$isValid) {
342+
$this->expectException(\UnexpectedValueException::class);
343+
$this->expectExceptionMessage("Value '$value' is not part of the enum " . EnumFixture::class);
344+
}
345+
346+
EnumFixture::assertValidValue($value);
347+
348+
self::assertTrue(EnumFixture::isValid($value));
349+
}
335350
}

0 commit comments

Comments
 (0)