mirror of
https://github.com/archtechx/enums.git
synced 2025-12-12 09:44:03 +00:00
Support defining #[Meta] on traits (resolve #9)
This commit is contained in:
parent
f0ea4c36c8
commit
365b3447f5
2 changed files with 53 additions and 5 deletions
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace ArchTech\Enums\Meta;
|
namespace ArchTech\Enums\Meta;
|
||||||
|
|
||||||
use ReflectionAttribute;
|
use ReflectionAttribute;
|
||||||
|
use ReflectionClass;
|
||||||
use ReflectionEnumUnitCase;
|
use ReflectionEnumUnitCase;
|
||||||
use ReflectionObject;
|
use ReflectionObject;
|
||||||
|
|
||||||
|
|
@ -19,12 +20,22 @@ class Reflection
|
||||||
public static function metaProperties(mixed $enum): array
|
public static function metaProperties(mixed $enum): array
|
||||||
{
|
{
|
||||||
$reflection = new ReflectionObject($enum);
|
$reflection = new ReflectionObject($enum);
|
||||||
|
$metaProperties = static::parseMetaProperties($reflection);
|
||||||
|
|
||||||
// Attributes of the `Meta` type
|
// Traits except the `Metadata` trait
|
||||||
$attributes = array_values(array_filter(
|
$traits = array_values(array_filter($reflection->getTraits(), fn (ReflectionClass $class) => $class->getName() !== 'ArchTech\Enums\Metadata'));
|
||||||
$reflection->getAttributes(),
|
|
||||||
fn (ReflectionAttribute $attr) => $attr->getName() === Meta::class,
|
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) {
|
if ($attributes) {
|
||||||
/** @var Meta $meta */
|
/** @var Meta $meta */
|
||||||
|
|
|
||||||
37
tests/Pest/TraitTest.php
Normal file
37
tests/Pest/TraitTest.php
Normal 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
|
||||||
|
{
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue