Skip to content

Instantly share code, notes, and snippets.

@innocenzi
Created January 19, 2026 02:14
Show Gist options
  • Select an option

  • Save innocenzi/e2cd788e204c6c780f143dbfccf1ab65 to your computer and use it in GitHub Desktop.

Select an option

Save innocenzi/e2cd788e204c6c780f143dbfccf1ab65 to your computer and use it in GitHub Desktop.
Type-safe enums using attributes for Laravel and Hybridly
<?php
namespace Infrastructure\Enum;
use Illuminate\Support\Collection;
use ReflectionAttribute;
use ReflectionEnumUnitCase;
/**
* Represents an enum that has metadata associated with its cases.
*
* @mixin \UnitEnum
*/
trait HasMetadata
{
/**
* Gets the value for the given metadata.
*
* @var class-string<Metadata> $metadata
*/
protected function getMetadataValue(string $metadata, null|string|array|int $default = null): null|string|array|int
{
return $this->getMetadataValues($metadata)->first() ?? $default;
}
/**
* Gets the values for the given metadata.
*
* @var class-string<Metadata> $metadata
*
* @return Collection<null|string|array|int>
*/
protected function getMetadataValues(string $metadata): Collection
{
return collect(new ReflectionEnumUnitCase(self::class, $this->name)->getAttributes())
->filter(fn (ReflectionAttribute $attribute) => $attribute->getName() === $metadata)
->map(fn (ReflectionAttribute $attribute) => $attribute->newInstance()->value());
}
}
<?php
namespace Infrastructure\Enum;
/**
* Represents an enum that provides its own serialization logic when rendered using Hybridly.
*/
interface HybridableEnumCase
{
/**
* Serializes the enum case into an array representation for Hybridly consumption.
*/
public function serialize(): array;
}
<?php
namespace Infrastructure\Enum;
use Illuminate\Support\Collection;
use Infrastructure\Enum\HybridableEnumCase;
use ReflectionAttribute;
use ReflectionEnumUnitCase;
/**
* Represents an enum that can be rendered with Hybridly.
*
* @mixin \UnitEnum
*/
trait IsHybridableEnum
{
public function toHybridArray(): array
{
return [
'value' => $this->value,
...$this->getHybridProperties(),
];
}
/**
* @return Collection<string,mixed>
*/
protected function getHybridProperties(): Collection
{
return collect(new ReflectionEnumUnitCase(self::class, $this->name)->getAttributes())
->filter(fn (ReflectionAttribute $attribute) => is_subclass_of($attribute->getName(), HybridableEnumCase::class))
->flatMap(fn (ReflectionAttribute $attribute) => $attribute->newInstance()->serialize());
}
}
<?php
namespace Infrastructure\Enum;
use Attribute;
use Infrastructure\Enum\HybridableEnumCase;
/**
* Represents a label that can be applied to an enum case.
*/
#[Attribute]
final class Label implements HybridableEnumCase, Metadata
{
public function __construct(
public readonly string $label,
) {}
public function value(): string
{
return $this->label;
}
public function serialize(): array
{
return ['label' => $this->label];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment