Passed
Branch feature/first-release (686b42)
by Andrea Marco
01:53
created

CasesCollection   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 274
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 34
eloc 43
c 3
b 0
f 0
dl 0
loc 274
ccs 62
cts 62
cp 1
rs 9.68

22 Methods

Rating   Name   Duplication   Size   Complexity  
A cases() 0 3 1
A __construct() 0 3 1
A values() 0 3 1
A first() 0 11 3
A names() 0 3 1
A keys() 0 3 1
A keyByName() 0 3 1
A keyByValue() 0 3 2
A pluck() 0 14 4
A count() 0 3 1
A keyBy() 0 9 2
A filter() 0 5 1
A except() 0 3 1
A sortDescBy() 0 7 2
A only() 0 3 1
A sortDesc() 0 3 1
A sort() 0 3 1
A onlyValues() 0 3 2
A sortBy() 0 7 1
A sortDescByValue() 0 3 2
A exceptValues() 0 3 2
A sortByValue() 0 3 2
1
<?php
2
3
namespace Cerbero\Enum;
4
5
use BackedEnum;
0 ignored issues
show
Bug introduced by
The type BackedEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
This use statement conflicts with another class in this namespace, Cerbero\Enum\BackedEnum. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use UnitEnum;
0 ignored issues
show
Bug introduced by
The type UnitEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
8
/**
9
 * The collection of enum cases.
10
 *
11
 */
12
class CasesCollection
13
{
14
    /**
15
     * Whether the cases belong to a backed enum
16
     *
17
     * @var bool
18
     */
19
    protected bool $enumIsBacked;
20
21
    /**
22
     * Instantiate the class
23
     *
24
     * @param array $cases
25
     */
26 56
    public function __construct(protected array $cases)
27
    {
28 56
        $this->enumIsBacked = $this->first() instanceof BackedEnum;
29
    }
30
31
    /**
32
     * Retrieve the cases
33
     *
34
     * @return array
35
     */
36 70
    public function cases(): array
37
    {
38 70
        return $this->cases;
39
    }
40
41
    /**
42
     * Retrieve the count of cases
43
     *
44
     * @return int
45
     */
46 2
    public function count(): int
47
    {
48 2
        return count($this->cases);
49
    }
50
51
    /**
52
     * Retrieve the first case
53
     *
54
     * @param callable|null $callback
55
     * @return mixed
56
     */
57 61
    public function first(callable $callback = null): mixed
58
    {
59 61
        $callback ??= fn () => true;
60
61 61
        foreach ($this->cases as $case) {
62 60
            if ($callback($case)) {
63 60
                return $case;
64
            }
65
        }
66
67 7
        return null;
68
    }
69
70
    /**
71
     * Retrieve the cases keyed by name
72
     *
73
     * @return array<string, mixed>
74
     */
75 2
    public function keyByName(): array
76
    {
77 2
        return $this->keyBy('name');
78
    }
79
80
    /**
81
     * Retrieve the cases keyed by the given key
82
     *
83
     * @param callable|string $key
84
     * @return array<string, mixed>
85
     */
86 7
    public function keyBy(callable|string $key): array
87
    {
88 7
        $result = [];
89
90 7
        foreach ($this->cases as $case) {
91 7
            $result[$case->get($key)] = $case;
92
        }
93
94 7
        return $result;
95
    }
96
97
    /**
98
     * Retrieve the cases keyed by value
99
     *
100
     * @return array<string, mixed>
101
     */
102 3
    public function keyByValue(): array
103
    {
104 3
        return $this->enumIsBacked ? $this->keyBy('value') : [];
105
    }
106
107
    /**
108
     * Retrieve all the names of the cases
109
     *
110
     * @return array<int, string>
111
     */
112 2
    public function names(): array
113
    {
114 2
        return array_column($this->cases, 'name');
115
    }
116
117
    /**
118
     * Retrieve all the values of the backed cases
119
     *
120
     * @return array<int, string|int>
121
     */
122 3
    public function values(): array
123
    {
124 3
        return array_column($this->cases, 'value');
125
    }
126
127
    /**
128
     * Retrieve all the keys of the cases
129
     *
130
     * @param callable|string $key
131
     * @return array
132
     */
133 4
    public function keys(callable|string $key): array
134
    {
135 4
        return $this->pluck($key);
136
    }
137
138
    /**
139
     * Retrieve an array of values optionally keyed by the given key
140
     *
141
     * @param callable|string|null $value
142
     * @param callable|string|null $key
143
     * @return array
144
     */
145 14
    public function pluck(callable|string $value = null, callable|string $key = null): array
146
    {
147 14
        $result = [];
148 14
        $value ??= $this->enumIsBacked ? 'value' : 'name';
149
150 14
        foreach ($this->cases as $case) {
151 14
            if ($key === null) {
152 10
                $result[] = $case->get($value);
153
            } else {
154 4
                $result[$case->get($key)] = $case->get($value);
155
            }
156
        }
157
158 12
        return $result;
159
    }
160
161
    /**
162
     * Retrieve a collection with the filtered cases
163
     *
164
     * @param callable $callback
165
     * @return static
166
     */
167 12
    public function filter(callable $callback): static
168
    {
169 12
        $cases = array_filter($this->cases, $callback);
170
171 12
        return new static(array_values($cases));
172
    }
173
174
    /**
175
     * Retrieve a collection of cases having the given names
176
     *
177
     * @param string ...$name
178
     * @return static
179
     */
180 2
    public function only(string ...$name): static
181
    {
182 2
        return $this->filter(fn (UnitEnum $case) => in_array($case->name, $name));
183
    }
184
185
    /**
186
     * Retrieve a collection of cases not having the given names
187
     *
188
     * @param string ...$name
189
     * @return static
190
     */
191 2
    public function except(string ...$name): static
192
    {
193 2
        return $this->filter(fn (UnitEnum $case) => !in_array($case->name, $name));
194
    }
195
196
    /**
197
     * Retrieve a collection of backed cases having the given values
198
     *
199
     * @param string|int ...$value
200
     * @return static
201
     */
202 3
    public function onlyValues(string|int ...$value): static
203
    {
204 3
        return $this->filter(fn (UnitEnum $case) => $this->enumIsBacked && in_array($case->value, $value, true));
205
    }
206
207
    /**
208
     * Retrieve a collection of backed cases not having the given values
209
     *
210
     * @param string|int ...$value
211
     * @return static
212
     */
213 3
    public function exceptValues(string|int ...$value): static
214
    {
215 3
        return $this->filter(fn (UnitEnum $case) => $this->enumIsBacked && !in_array($case->value, $value, true));
216
    }
217
218
    /**
219
     * Retrieve a collection of cases sorted by name ascending
220
     *
221
     * @return static
222
     */
223 2
    public function sort(): static
224
    {
225 2
        return $this->sortBy('name');
226
    }
227
228
    /**
229
     * Retrieve a collection of cases sorted by name descending
230
     *
231
     * @return static
232
     */
233 2
    public function sortDesc(): static
234
    {
235 2
        return $this->sortDescBy('name');
236
    }
237
238
    /**
239
     * Retrieve a collection of cases sorted by the given key ascending
240
     *
241
     * @param callable|string $key
242
     * @return static
243
     */
244 6
    public function sortBy(callable|string $key): static
245
    {
246 6
        $cases = $this->cases;
247
248 6
        usort($cases, fn ($a, $b) => $a->get($key) <=> $b->get($key));
249
250 6
        return new static($cases);
251
    }
252
253
    /**
254
     * Retrieve a collection of cases sorted by the given key descending
255
     *
256
     * @param callable|string $key
257
     * @return static
258
     */
259 6
    public function sortDescBy(callable|string $key): static
260
    {
261 6
        $cases = $this->cases;
262
263 6
        usort($cases, fn ($a, $b) => $a->get($key) > $b->get($key) ? -1 : 1);
264
265 6
        return new static($cases);
266
    }
267
268
    /**
269
     * Retrieve a collection of cases sorted by value ascending
270
     *
271
     * @return static
272
     */
273 2
    public function sortByValue(): static
274
    {
275 2
        return $this->enumIsBacked ? $this->sortBy('value') : new static([]);
276
    }
277
278
    /**
279
     * Retrieve a collection of cases sorted by value descending
280
     *
281
     * @return static
282
     */
283 2
    public function sortDescByValue(): static
284
    {
285 2
        return $this->enumIsBacked ? $this->sortDescBy('value') : new static([]);
286
    }
287
}
288