Skip to content

Commit

Permalink
enum
Browse files Browse the repository at this point in the history
  • Loading branch information
teodoroleckie committed May 1, 2021
1 parent 1325f77 commit 33f9204
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 19 deletions.
32 changes: 22 additions & 10 deletions src/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
class Enum implements EnumInterface
{
/** @var array */
private static array $constants;
private static array $constants = [];

protected static array $instances = [];

/** @var mixed */
private mixed $value;
Expand All @@ -33,11 +35,10 @@ class Enum implements EnumInterface
*/
final public function __construct(mixed $value)
{
static::$constants = static::constants();

$value = ($value instanceof EnumInterface) ? $value->getValue() : $value;

$this->key = static::searchNameByValue($value);

$this->value = $value;
}

Expand All @@ -46,9 +47,15 @@ final public function __construct(mixed $value)
*/
private static function constants(): array
{
if (isset(static::$constants[static::class])) {
return static::$constants[static::class];
}

$reflection = new ReflectionClass(static::class);

return $reflection->getConstants();
static::$constants[static::class] = $reflection->getConstants();

return static::$constants[static::class];
}

/**
Expand All @@ -65,7 +72,7 @@ public function getValue(): mixed
*/
private static function searchNameByValue(mixed $value): string
{
$name = array_search($value, static::$constants, true);
$name = array_search($value, static::constants(), true);
if (false === $name) {
throw new InvalidArgumentException(sprintf('Constant value [%s] not found', $value));
}
Expand All @@ -80,27 +87,32 @@ private static function searchNameByValue(mixed $value): string
*/
final public static function __callStatic(string $name, array $arguments): self
{
if (!array_key_exists($name, static::$constants)) {
if (!array_key_exists($name, static::constants())) {
throw new InvalidArgumentException(sprintf('Constant [%s] is not defined', $name));
}
if (isset(static::$instances[static::class][$name])) {
return static::$instances[static::class][$name];
}

static::$instances[static::class][$name] = new static(static::constants()[$name]);

return new static(static::$constants[$name]);
return static::$instances[static::class][$name];
}

/**
* @return mixed[]
*/
public function getValues(): array
{
return array_values(static::$constants);
return array_values(static::$constants[static::class]);
}

/**
* @return string[]
*/
public function getKeys(): array
{
return array_keys(static::$constants);
return array_keys(static::$constants[static::class]);
}

/**
Expand All @@ -116,7 +128,7 @@ public function getKey(): string
*/
public function toArray(): array
{
return static::$constants;
return static::$constants[static::class];
}

/**
Expand Down
18 changes: 9 additions & 9 deletions tests/EnumTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function invalidMethod(): void
public function keysValues(): void
{
$this->enum = new DummyEnum(5);
static::assertEquals(["VALUE", "OTHER", "PRODUCT"], $this->enum->getKeys());
static::assertEquals(["VALUE1", "VALUE2", "VALUE5"], $this->enum->getKeys());
static::assertEquals([0 => 1, 1=> 2, 2=> 5], $this->enum->getValues());
}

Expand All @@ -66,22 +66,22 @@ public function callDataProvider(): array

return [
[
"1", $this->enum::VALUE()
"1", $this->enum::VALUE1()
],
[
"2", $this->enum::OTHER(),
"2", $this->enum::VALUE2(),
],
[
"5", new DummyEnum(new DummyEnum(5)),
],
[
5, $this->enum->getValue(),
"5", $this->enum->getValue(),
],
[
"PRODUCT", $this->enum->getKey(),
"VALUE5", $this->enum->getKey(),
],
[
["VALUE" => 1, "OTHER" => 2, "PRODUCT" => 5], $this->enum->toArray(),
["VALUE1" => 1, "VALUE2" => 2, "VALUE5" => 5], $this->enum->toArray(),
]
];
}
Expand All @@ -96,9 +96,9 @@ public function callDataProvider(): array
*/
class DummyEnum extends Enum
{
public const VALUE = 1;
public const VALUE1 = 1;

public const OTHER = 2;
public const VALUE2 = 2;

public const PRODUCT = 5;
public const VALUE5 = 5;
}

0 comments on commit 33f9204

Please sign in to comment.