1
0
Fork 0
mirror of https://github.com/archtechx/enums.git synced 2025-12-12 05:24:03 +00:00

Support defining #[Meta] on traits (resolve #9)

This commit is contained in:
Samuel Štancl 2024-01-12 22:35:58 +01:00
parent f0ea4c36c8
commit 365b3447f5
2 changed files with 53 additions and 5 deletions

View file

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace ArchTech\Enums\Meta;
use ReflectionAttribute;
use ReflectionClass;
use ReflectionEnumUnitCase;
use ReflectionObject;
@ -19,12 +20,22 @@ class Reflection
public static function metaProperties(mixed $enum): array
{
$reflection = new ReflectionObject($enum);
$metaProperties = static::parseMetaProperties($reflection);
// Attributes of the `Meta` type
$attributes = array_values(array_filter(
$reflection->getAttributes(),
fn (ReflectionAttribute $attr) => $attr->getName() === Meta::class,
));
// Traits except the `Metadata` trait
$traits = array_values(array_filter($reflection->getTraits(), fn (ReflectionClass $class) => $class->getName() !== 'ArchTech\Enums\Metadata'));
foreach ($traits as $trait) {
$metaProperties = array_merge($metaProperties, static::parseMetaProperties($trait));
}
return $metaProperties;
}
protected static function parseMetaProperties(ReflectionClass $reflection): array
{
// Only the `Meta` attribute
$attributes = $reflection->getAttributes(Meta::class);
if ($attributes) {
/** @var Meta $meta */

37
tests/Pest/TraitTest.php Normal file
View file

@ -0,0 +1,37 @@
<?php
use ArchTech\Enums\Meta\Meta;
use ArchTech\Enums\Meta\MetaProperty;
use ArchTech\Enums\Metadata;
test('enums can use traits which define meta properties on themselves', function () {
expect(MyEnum::FOO->description())->toBe('Foo!');
expect(MyEnum::BAR->description())->toBe('Bar!');
expect(MyEnum::BAZ->description())->toBe(null);
});
enum MyEnum
{
use Metadata;
use HasDescription;
#[Description('Foo!')]
case FOO;
#[Description('Bar!')]
case BAR;
case BAZ;
}
#[Attribute]
class Description extends MetaProperty
{}
/**
* @method string|null description()
*/
#[Meta(Description::class)]
trait HasDescription
{
}