Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow to provide extra values to EnumCase attribute
- Loading branch information
Showing
10 changed files
with
375 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "elao/enum" package. | ||
* | ||
* Copyright (C) Elao | ||
* | ||
* @author Elao <contact@elao.com> | ||
*/ | ||
|
||
namespace Elao\Enum; | ||
|
||
use Elao\Enum\Attribute\EnumCase; | ||
|
||
trait EnumCaseAttributesTrait | ||
{ | ||
private function getEnumCaseAttribute(): ?EnumCase | ||
{ | ||
return static::enumCaseAttributes()[$this] ?? null; | ||
} | ||
|
||
/** | ||
* @return \SplObjectStorage<\UnitEnum,EnumCase> | ||
*/ | ||
private static function enumCaseAttributes(): \SplObjectStorage | ||
{ | ||
static $attributes; | ||
|
||
if (!isset($attributes)) { | ||
$attributes = new \SplObjectStorage(); | ||
|
||
foreach ((new \ReflectionEnum(static::class))->getCases() as $rCase) { | ||
if (null === $rAttr = $rCase->getAttributes(EnumCase::class)[0] ?? null) { | ||
continue; | ||
} | ||
|
||
/** @var EnumCase $attr */ | ||
$attr = $rAttr->newInstance(); | ||
|
||
$attributes[$rCase->getValue()] = $attr; | ||
} | ||
} | ||
|
||
return $attributes; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "elao/enum" package. | ||
* | ||
* Copyright (C) Elao | ||
* | ||
* @author Elao <contact@elao.com> | ||
*/ | ||
|
||
namespace Elao\Enum; | ||
|
||
trait ExtrasTrait | ||
{ | ||
use EnumCaseAttributesTrait; | ||
|
||
public function getExtra(string $key, bool $throwOnMissingExtra = false): mixed | ||
{ | ||
if ($throwOnMissingExtra && !isset(static::arrayAccessibleExtras()[$this][$key])) { | ||
throw new \InvalidArgumentException(sprintf( | ||
'No value for extra "%s" for enum case %s::%s', | ||
$key, | ||
__CLASS__, | ||
$this->name, | ||
)); | ||
} | ||
|
||
return static::arrayAccessibleExtras()[$this][$key] ?? null; | ||
} | ||
|
||
/** | ||
* @return iterable<static, mixed> | ||
*/ | ||
public static function extras(string $key, bool $throwOnMissingExtra = false): iterable | ||
{ | ||
/** @var static $case */ | ||
foreach (static::cases() as $case) { | ||
yield $case => $case->getExtra($key, $throwOnMissingExtra); | ||
} | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
private static function arrayAccessibleExtras(): \SplObjectStorage | ||
{ | ||
static $extras; | ||
|
||
if (!isset($extras)) { | ||
$extras = new \SplObjectStorage(); | ||
|
||
/** @var static $case */ | ||
foreach (static::cases() as $case) { | ||
$extras[$case] = $case->getEnumCaseAttribute()?->extras; | ||
} | ||
} | ||
|
||
return $extras; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "elao/enum" package. | ||
* | ||
* Copyright (C) Elao | ||
* | ||
* @author Elao <contact@elao.com> | ||
*/ | ||
|
||
namespace Elao\Enum\Tests\Fixtures\Enum; | ||
|
||
use Elao\Enum\Attribute\EnumCase; | ||
use Elao\Enum\ExtrasTrait; | ||
|
||
enum SuitWithExtras | ||
{ | ||
use ExtrasTrait; | ||
|
||
#[EnumCase(extras: ['icon' => 'fa-heart', 'color' => 'red', 'only-for-hearts' => 'value'])] | ||
case Hearts; | ||
|
||
#[EnumCase(extras: ['icon' => 'fa-diamond', 'color' => 'red'])] | ||
case Diamonds; | ||
|
||
#[EnumCase(extras: ['icon' => 'fa-club', 'color' => 'black'])] | ||
case Clubs; | ||
|
||
#[EnumCase(extras: ['icon' => 'fa-spade', 'color' => 'black'])] | ||
case Spades; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "elao/enum" package. | ||
* | ||
* Copyright (C) Elao | ||
* | ||
* @author Elao <contact@elao.com> | ||
*/ | ||
|
||
namespace Elao\Enum\Tests; | ||
|
||
use PHPUnit\Framework\Assert; | ||
|
||
trait IterableAssertionsTrait | ||
{ | ||
private static function iterates(iterable $iterable): void | ||
{ | ||
foreach ($iterable as $_) { | ||
} | ||
} | ||
|
||
private static function assertIterablesMatch(iterable $expected, iterable $iterable) | ||
{ | ||
$keys = []; | ||
$values = []; | ||
foreach ($iterable as $key => $value) { | ||
$keys[] = $key; | ||
$values[] = $value; | ||
} | ||
|
||
$expectedKeys = []; | ||
$expectedValues = []; | ||
foreach ($expected as $key => $value) { | ||
$expectedKeys[] = $key; | ||
$expectedValues[] = $value; | ||
} | ||
|
||
Assert::assertSame($keys, $expectedKeys, 'iterator keys are identical'); | ||
Assert::assertSame($values, $expectedValues, 'iterator values are identical'); | ||
} | ||
} |
Oops, something went wrong.