Skip to content

Commit e1b3b96

Browse files
committed
simplify
1 parent 4478475 commit e1b3b96

File tree

7 files changed

+134
-112
lines changed

7 files changed

+134
-112
lines changed

src/Enum.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22

33
namespace Utilitte\Enum;
44

5-
abstract class Enum extends EnumAbstract
5+
use Utilitte\Enum\Exceptions\InvalidArgumentException;
6+
use Utilitte\Enum\Storage\EnumStorage;
7+
8+
/**
9+
* @internal
10+
*/
11+
abstract class Enum
612
{
713

14+
/** @var EnumStorage[] */
15+
private static array $storages = [];
16+
817
private string $value;
918

1019
final protected function __construct(string $value)
@@ -17,6 +26,36 @@ public function value(): string
1726
return $this->value;
1827
}
1928

29+
/**
30+
* @return string[]
31+
*/
32+
abstract protected static function getEnums(): array;
33+
34+
/**
35+
* @param mixed[] $arguments
36+
*/
37+
final public static function __callStatic(string $name, array $arguments)
38+
{
39+
if ($name !== strtoupper($name)) {
40+
throw new InvalidArgumentException(sprintf('Called static class must be uppercase, %s given', $name));
41+
}
42+
43+
return self::getStorage()->getEntry($name)->getEnum();
44+
}
45+
46+
private static function getStorage(): EnumStorage
47+
{
48+
if (!isset(self::$storages[static::class])) {
49+
self::$storages[static::class] = new EnumStorage(
50+
static::class,
51+
fn(string $value) => new static($value),
52+
new EnumMapping(static::getEnums())
53+
);
54+
}
55+
56+
return self::$storages[static::class];
57+
}
58+
2059
public function __toString(): string
2160
{
2261
return $this->value;

src/EnumAbstract.php

Lines changed: 0 additions & 84 deletions
This file was deleted.

src/EnumMapping.php

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,22 @@
55
final class EnumMapping
66
{
77

8-
/** @var string[] */
8+
/** @var bool[] */
99
private array $mapping = [];
1010

11-
private string $class;
12-
1311
/**
14-
* @param bool[] $mapping
12+
* @param string[] $mapping
1513
*/
16-
public function __construct(string $class, array $mapping)
14+
public function __construct(array $mapping)
1715
{
18-
$this->class = $class;
19-
foreach ($mapping as $key => $bool) {
20-
$this->mapping[strtoupper($key)] = $key;
16+
foreach ($mapping as $key) {
17+
$this->mapping[strtoupper($key)] = true;
2118
}
2219
}
2320

24-
public function getClass(): string
25-
{
26-
return $this->class;
27-
}
28-
29-
public function callableGetter(): callable
30-
{
31-
return [$this->getClass(), 'get'];
32-
}
33-
34-
/**
35-
* @return string[]
36-
*/
37-
public function getMapping(): array
21+
public function has(string $key): bool
3822
{
39-
return $this->mapping;
23+
return isset($this->mapping[$key]);
4024
}
4125

4226
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Utilitte\Enum\Exceptions;
4+
5+
use Exception;
6+
7+
class EnumNotExistsException extends Exception
8+
{
9+
10+
public function __construct(string $class, string $key)
11+
{
12+
parent::__construct(sprintf('Enum %s::%s not exists', $class, $key));
13+
}
14+
15+
}

src/Storage/EnumEntry.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Utilitte\Enum\Storage;
4+
5+
use Utilitte\Enum\Enum;
6+
use Utilitte\Enum\Exceptions\EnumNotExistsException;
7+
8+
final class EnumEntry
9+
{
10+
11+
private string $key;
12+
13+
private string $value;
14+
15+
private string $class;
16+
17+
private bool $isset;
18+
19+
/** @var callable */
20+
private $factory;
21+
22+
private Enum $enum;
23+
24+
public function __construct(string $key, string $value, string $class, bool $isset, callable $factory)
25+
{
26+
$this->key = $key;
27+
$this->value = $value;
28+
$this->isset = $isset;
29+
$this->factory = $factory;
30+
$this->class = $class;
31+
}
32+
33+
public function getEnum(): Enum
34+
{
35+
if (!$this->isset) {
36+
throw new EnumNotExistsException($this->class, $this->key);
37+
}
38+
39+
if (!isset($this->enum)) {
40+
$this->enum = ($this->factory)($this->value);
41+
}
42+
43+
return $this->enum;
44+
}
45+
46+
}

src/Storage/EnumStorage.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Utilitte\Enum\Storage;
44

55
use Utilitte\Enum\Enum;
6+
use Utilitte\Enum\EnumMapping;
67
use Utilitte\Enum\Exceptions\InvalidArgumentException;
78
use Utilitte\Enum\Exceptions\UnexpectedValueException;
89

@@ -12,11 +13,33 @@ class EnumStorage
1213
/** @var Enum[] */
1314
private array $storage = [];
1415

16+
/** @var EnumEntry[] */
17+
private array $entries = [];
18+
1519
private string $class;
1620

17-
public function __construct(string $class)
21+
/** @var callable */
22+
private $factory;
23+
24+
private EnumMapping $mapping;
25+
26+
public function __construct(string $class, callable $factory, EnumMapping $mapping)
1827
{
1928
$this->class = $class;
29+
$this->factory = $factory;
30+
$this->mapping = $mapping;
31+
}
32+
33+
public function getEntry(string $name): EnumEntry
34+
{
35+
$key = strtoupper($name);
36+
$value = strtolower($name);
37+
38+
if (!isset($this->entries[$key])) {
39+
$this->entries[$key] = new EnumEntry($key, $value, $this->class, $this->mapping->has($key), $this->factory);
40+
}
41+
42+
return $this->entries[$key];
2043
}
2144

2245
public function has(string $name): bool

tests/EnumTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Tests;
44

55
use Codeception\Test\Unit;
6+
use Utilitte\Enum\Exceptions\EnumNotExistsException;
67
use Utilitte\Enum\Exceptions\InvalidArgumentException;
78
use Utilitte\Tests\TestEnum;
89

@@ -12,9 +13,7 @@ class EnumTest extends Unit
1213
public function testEnum()
1314
{
1415
$this->assertSame(TestEnum::GET_ENUM(), TestEnum::GET_ENUM());
15-
$this->assertSame(TestEnum::get('get_enum'), TestEnum::GET_ENUM());
1616
$this->assertEquals('get_enum', TestEnum::GET_ENUM()->value());
17-
$this->assertEquals('get_enum', TestEnum::get('get_enum')->value());
1817
}
1918

2019
public function testInvalidCase()
@@ -26,7 +25,7 @@ public function testInvalidCase()
2625

2726
public function testInvalidMethod()
2827
{
29-
$this->expectException(InvalidArgumentException::class);
28+
$this->expectException(EnumNotExistsException::class);
3029

3130
TestEnum::GET_ENUMS();
3231
}

0 commit comments

Comments
 (0)