Re: [Discussion] Implicitly backed enums

From: Date: Wed, 22 May 2024 00:48:00 +0000
Subject: Re: [Discussion] Implicitly backed enums
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message

> 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



Thread (21 messages)

« previous php.internals (#123395) next »