Skip to content

Commit 0c87357

Browse files
authored
Extend functionality to work with pure enums (#6)
* Extend functionality to work with pure enums * Code review changes Altered `::values()` to act like `::names()` for backed enums, code style fixes, general cleanups
1 parent 20fa78c commit 0c87357

File tree

9 files changed

+109
-16
lines changed

9 files changed

+109
-16
lines changed

README.md

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ composer require archtechx/enums
2121

2222
### InvokableCases
2323

24-
This helper lets you get the value of a backed enum by "invoking" it — either statically (`MyEnum::FOO()` instead of `MyEnum::FOO`), or as an instance (`$enum()`).
24+
This helper lets you get the value of a backed enum, or the name of a pure enum, by "invoking" it — either statically (`MyEnum::FOO()` instead of `MyEnum::FOO`), or as an instance (`$enum()`).
2525

2626
That way, you can use enums as array keys:
2727
```php
@@ -58,20 +58,32 @@ enum TaskStatus: int
5858
case COMPLETED = 1;
5959
case CANCELED = 2;
6060
}
61+
62+
enum Role
63+
{
64+
use InvokableCases;
65+
66+
case ADMINISTRATOR;
67+
case SUBSCRIBER;
68+
case GUEST;
69+
}
6170
```
6271

6372
#### Use static calls to get the primitive value
6473
```php
6574
TaskStatus::INCOMPLETE(); // 0
6675
TaskStatus::COMPLETED(); // 1
6776
TaskStatus::CANCELED(); // 2
77+
Role::ADMINISTRATOR(); // 'ADMINISTRATOR'
78+
Role::SUBSCRIBER(); // 'SUBSCRIBER'
79+
Role::GUEST(); // 'GUEST'
6880
```
6981

7082
#### Invoke instances to get the primitive value
7183
```php
72-
public function updateStatus(TaskStatus $status)
84+
public function updateStatus(TaskStatus $status, Role $role)
7385
{
74-
$this->record->setStatus($status());
86+
$this->record->setStatus($status(), $role());
7587
}
7688
```
7789

@@ -91,16 +103,26 @@ enum TaskStatus: int
91103
case COMPLETED = 1;
92104
case CANCELED = 2;
93105
}
106+
107+
enum Role
108+
{
109+
use Names;
110+
111+
case ADMINISTRATOR;
112+
case SUBSCRIBER;
113+
case GUEST;
114+
}
94115
```
95116

96117
#### Use the `names()` method
97118
```php
98119
TaskStatus::names(); // ['INCOMPLETE', 'COMPLETED', 'CANCELED']
120+
Role::names(); // ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
99121
```
100122

101123
### Values
102124

103-
This helper returns a list of case *values* in the enum.
125+
This helper returns a list of case *values* for backed enums, or a list of case *names* for pure enums (making this functionally equivalent to [`::names()`](#names) for pure Enums)
104126

105127
#### Apply the trait on your enum
106128
```php
@@ -114,16 +136,26 @@ enum TaskStatus: int
114136
case COMPLETED = 1;
115137
case CANCELED = 2;
116138
}
139+
140+
enum Role
141+
{
142+
use Values;
143+
144+
case ADMINISTRATOR;
145+
case SUBSCRIBER;
146+
case GUEST;
147+
}
117148
```
118149

119150
#### Use the `values()` method
120151
```php
121152
TaskStatus::values(); // [0, 1, 2]
153+
Role::values(); // ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
122154
```
123155

124156
### Options
125157

126-
This helper returns an associative array of case names and values.
158+
This helper returns an associative array of case names and values for backed enums, or a list of names for pure enums (making this functionally equivalent to [`::names()`](#names) for pure Enums).
127159

128160
#### Apply the trait on your enum
129161
```php
@@ -137,11 +169,21 @@ enum TaskStatus: int
137169
case COMPLETED = 1;
138170
case CANCELED = 2;
139171
}
172+
173+
enum Role
174+
{
175+
use Options;
176+
177+
case ADMINISTRATOR;
178+
case SUBSCRIBER;
179+
case GUEST;
180+
}
140181
```
141182

142183
#### Use the `options()` method
143184
```php
144185
TaskStatus::options(); // ['INCOMPLETE' => 0, 'COMPLETED' => 1, 'CANCELED' => 2]
186+
Role::options(); // ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
145187
```
146188

147189
## Development

src/InvokableCases.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,24 @@
44

55
namespace ArchTech\Enums;
66

7+
use BackedEnum;
8+
79
trait InvokableCases
810
{
911
/** Return the enum's value when it's $invoked(). */
1012
public function __invoke()
1113
{
12-
return $this->value;
14+
return $this instanceof BackedEnum ? $this->value : $this->name;
1315
}
1416

15-
/** Return the enum's value when it's called ::STATICALLY(). */
17+
/** Return the enum's value or name when it's called ::STATICALLY(). */
1618
public static function __callStatic($name, $args)
1719
{
1820
$cases = static::cases();
1921

2022
foreach ($cases as $case) {
2123
if ($case->name === $name) {
22-
return $case->value;
24+
return $case instanceof BackedEnum ? $case->value : $case->name;
2325
}
2426
}
2527

src/Options.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44

55
namespace ArchTech\Enums;
66

7+
use BackedEnum;
8+
79
trait Options
810
{
911
/** Get an associative array of [case name => case value]. */
1012
public static function options(): array
1113
{
12-
return array_column(static::cases(), 'value', 'name');
14+
$cases = static::cases();
15+
16+
return isset($cases[0]) && $cases[0] instanceof BackedEnum
17+
? array_column($cases, 'value', 'name')
18+
: array_column($cases, 'name');
1319
}
1420
}

src/Values.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44

55
namespace ArchTech\Enums;
66

7+
use BackedEnum;
8+
79
trait Values
810
{
911
/** Get an array of case values. */
1012
public static function values(): array
1113
{
12-
return array_column(static::cases(), 'value');
14+
$cases = static::cases();
15+
16+
return isset($cases[0]) && $cases[0] instanceof BackedEnum
17+
? array_column($cases, 'value')
18+
: array_column($cases, 'name');
1319
}
1420
}

tests/Pest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,11 @@ enum Status: int
5656
case PENDING = 0;
5757
case DONE = 1;
5858
}
59+
60+
enum Role
61+
{
62+
use InvokableCases, Options, Names, Values;
63+
64+
case ADMIN;
65+
case GUEST;
66+
}

tests/Pest/InvokableCasesTest.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,33 @@
22

33
use ArchTech\Enums\Exceptions\UndefinedCaseError;
44

5-
it('can be used as a static method', function () {
5+
it('can be used as a static method with backed enums', function () {
66
expect(Status::PENDING())->toBe(0);
77
expect(Status::DONE())->toBe(1);
88
});
99

10-
it('can be invoked as an instance', function () {
10+
it('can be used as a static method with pure enums', function () {
11+
expect(Role::ADMIN())->toBe('ADMIN');
12+
expect(Role::GUEST())->toBe('GUEST');
13+
});
14+
15+
it('can be invoked as an instance as a backed enum', function () {
1116
$status = Status::PENDING;
1217

1318
expect($status())->toBe(0);
1419
expect($status())->toBe($status->value);
1520
});
1621

17-
it('throws an error when a nonexistent case is being used', function () {
22+
it('can be invoked as an instance as a pure enum', function () {
23+
$role = Role::ADMIN;
24+
25+
expect($role())->toBe('ADMIN');
26+
});
27+
28+
it('throws an error when a nonexistent case is being used for backed enums', function () {
1829
Status::INVALID();
1930
})->expectException(UndefinedCaseError::class);
31+
32+
it('throws an error when a nonexistent case is being used for pure enums', function () {
33+
Role::INVALID();
34+
})->expectException(UndefinedCaseError::class);

tests/Pest/NamesTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<?php
22

3-
it('can return an array of case names')
3+
it('can return an array of case names from backed enums')
44
->expect(Status::names())
55
->toBe(['PENDING', 'DONE']);
6+
7+
it('can return an array of case names from pure enums')
8+
->expect(Role::names())
9+
->toBe(['ADMIN', 'GUEST']);

tests/Pest/OptionsTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<?php
22

3-
it('can return an associative array of options')
3+
it('can return an associative array of options from a backed enum')
44
->expect(Status::options())->toBe([
55
'PENDING' => 0,
66
'DONE' => 1,
77
]);
8+
9+
it('can return an indexed array of options from a pure enum')
10+
->expect(Role::options())->toBe([
11+
0 => 'ADMIN',
12+
1 => 'GUEST',
13+
]);

tests/Pest/ValuesTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<?php
22

3-
it('can return an array of case values')
3+
it('can return an array of case values from a backed enum')
44
->expect(Status::values())
55
->toBe([0, 1]);
6+
7+
it('can return an array of case names from a pure enum')
8+
->expect(Role::values())
9+
->toBe(['ADMIN', 'GUEST']);

0 commit comments

Comments
 (0)