> On May 21, 2024, at 6:47 PM, Bilge <[email protected]> wrote:
>
> On 22/05/2024 00:31, Larry Garfield wrote:
>> I could see an argument for auto-populating the backing value off the enum name if
>> it's not specified, something like this:
>> enum Options: string {
>> case First; // This implicitly gets "First"
>> case Second = '2nd';
>> }
> This seems like a reasonable compromise. In this case, all I need to do is change my enum to a
> backed enum (suffix : string
) and I get the benefits of implicit values. I still like
> the idea of the same being possible for non-backed enums, though I imagine that is a product of my
> naïveté, as I do not tend to think of things in the framing of (de)serialization.
>
>> I'm not sure if I'd support it myself at the moment
> Noted, but I once again find myself needing to ask: why not? Were it up to me, I'd say
> let's start right now! :)
>
> Aside, I am not at all concerned with integer-backed enums at this juncture, and presume that
> could be a separate discussion/implementation anyway.
>
> Cheers,
> Bilge
>
As a workaround, you can use something like the trait below.
```
trait SerializableEnum
{
public readonly string $name;
/** @return list<self> */
abstract public static function cases(): array;
public function toString(): string
{
return $this->name;
}
public static function from(string $name): self
{
return self::tryFrom($name) ?? throw new ValueError(sprintf(
'"%s" is not a valid backing value for enum %s',
$name,
self::class,
));
}
public static function tryFrom(string $name): ?self
{
foreach (self::cases() as $case) {
if ($case->name === $name) {
return $case;
}
}
return null;
}
}
enum ExampleEnum
{
use SerializableEnum;
case ONE;
case TWO;
case THREE;
}
var_dump(ExampleEnum::from('ONE'));
var_dump(ExampleEnum::from('FOUR'));
```
Perhaps not as clean and easy as the functionality being built-in, but it gets the job done. :-D
Aaron Piotrowski