Skip to content

Commit

Permalink
Merge branch 'release/1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
cerbero90 committed Jul 12, 2022
2 parents fc9d27f + 635123f commit 42a16a8
Show file tree
Hide file tree
Showing 17 changed files with 2,231 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
php-version: 8.1
extensions: dom, curl, libxml, mbstring, zip
tools: composer:v2
coverage: xdebug
Expand Down
3 changes: 3 additions & 0 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
build:
image: default-bionic
environment:
php: 8.1.2
nodes:
analysis:
project_setup:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi

### Security
- Nothing


## 1.0.0 - 2022-07-12

### Added
- First implementation of the package
355 changes: 352 additions & 3 deletions README.md

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
}
},
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true
}
}
}
312 changes: 312 additions & 0 deletions src/CasesCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
<?php

namespace Cerbero\Enum;

use BackedEnum;
use Countable;
use IteratorAggregate;
use Traversable;
use UnitEnum;

/**
* The collection of enum cases.
*
*/
class CasesCollection implements Countable, IteratorAggregate
{
/**
* Whether the cases belong to a backed enum
*
* @var bool
*/
protected bool $enumIsBacked;

/**
* Instantiate the class
*
* @param array $cases
*/
public function __construct(protected array $cases)
{
$this->enumIsBacked = $this->first() instanceof BackedEnum;
}

/**
* Retrieve the iterable cases
*
* @return Traversable
*/
public function getIterator(): Traversable
{
return (function () {
foreach ($this->cases as $case) {
yield $case;
}
})();
}

/**
* Retrieve the cases
*
* @return array
*/
public function cases(): array
{
return $this->cases;
}

/**
* Retrieve the count of cases
*
* @return int
*/
public function count(): int
{
return count($this->cases);
}

/**
* Retrieve the first case
*
* @param callable|null $callback
* @param mixed $default
* @return mixed
*/
public function first(callable $callback = null, mixed $default = null): mixed
{
$callback ??= fn () => true;

foreach ($this->cases as $case) {
if ($callback($case)) {
return $case;
}
}

return $default;
}

/**
* Retrieve the cases keyed by name
*
* @return array<string, mixed>
*/
public function keyByName(): array
{
return $this->keyBy('name');
}

/**
* Retrieve the cases keyed by the given key
*
* @param callable|string $key
* @return array<string, mixed>
*/
public function keyBy(callable|string $key): array
{
$result = [];

foreach ($this->cases as $case) {
$result[$case->get($key)] = $case;
}

return $result;
}

/**
* Retrieve the cases keyed by value
*
* @return array<string, mixed>
*/
public function keyByValue(): array
{
return $this->enumIsBacked ? $this->keyBy('value') : [];
}

/**
* Retrieve the cases grouped by the given key
*
* @param callable|string $key
* @return array<string, mixed>
*/
public function groupBy(callable|string $key): array
{
$result = [];

foreach ($this->cases as $case) {
$result[$case->get($key)][] = $case;
}

return $result;
}

/**
* Retrieve all the names of the cases
*
* @return array<int, string>
*/
public function names(): array
{
return array_column($this->cases, 'name');
}

/**
* Retrieve all the values of the backed cases
*
* @return array<int, string|int>
*/
public function values(): array
{
return array_column($this->cases, 'value');
}

/**
* Retrieve an array of values optionally keyed by the given key
*
* @param callable|string|null $value
* @param callable|string|null $key
* @return array
*/
public function pluck(callable|string $value = null, callable|string $key = null): array
{
$result = [];
$value ??= $this->enumIsBacked ? 'value' : 'name';

foreach ($this->cases as $case) {
if ($key === null) {
$result[] = $case->get($value);
} else {
$result[$case->get($key)] = $case->get($value);
}
}

return $result;
}

/**
* Retrieve a collection with the filtered cases
*
* @param callable|string $filter
* @return static
*/
public function filter(callable|string $filter): static
{
$callback = is_callable($filter) ? $filter : fn (mixed $case) => $case->get($filter) === true;
$cases = array_filter($this->cases, $callback);

return new static(array_values($cases));
}

/**
* Retrieve a collection of cases having the given names
*
* @param string ...$name
* @return static
*/
public function only(string ...$name): static
{
return $this->filter(fn (UnitEnum $case) => in_array($case->name, $name));
}

/**
* Retrieve a collection of cases not having the given names
*
* @param string ...$name
* @return static
*/
public function except(string ...$name): static
{
return $this->filter(fn (UnitEnum $case) => !in_array($case->name, $name));
}

/**
* Retrieve a collection of backed cases having the given values
*
* @param string|int ...$value
* @return static
*/
public function onlyValues(string|int ...$value): static
{
return $this->filter(fn (UnitEnum $case) => $this->enumIsBacked && in_array($case->value, $value, true));
}

/**
* Retrieve a collection of backed cases not having the given values
*
* @param string|int ...$value
* @return static
*/
public function exceptValues(string|int ...$value): static
{
return $this->filter(fn (UnitEnum $case) => $this->enumIsBacked && !in_array($case->value, $value, true));
}

/**
* Retrieve a collection of cases sorted by name ascending
*
* @return static
*/
public function sort(): static
{
return $this->sortBy('name');
}

/**
* Retrieve a collection of cases sorted by name descending
*
* @return static
*/
public function sortDesc(): static
{
return $this->sortDescBy('name');
}

/**
* Retrieve a collection of cases sorted by the given key ascending
*
* @param callable|string $key
* @return static
*/
public function sortBy(callable|string $key): static
{
$cases = $this->cases;

usort($cases, fn ($a, $b) => $a->get($key) <=> $b->get($key));

return new static($cases);
}

/**
* Retrieve a collection of cases sorted by the given key descending
*
* @param callable|string $key
* @return static
*/
public function sortDescBy(callable|string $key): static
{
$cases = $this->cases;

usort($cases, fn ($a, $b) => $a->get($key) > $b->get($key) ? -1 : 1);

return new static($cases);
}

/**
* Retrieve a collection of cases sorted by value ascending
*
* @return static
*/
public function sortByValue(): static
{
return $this->enumIsBacked ? $this->sortBy('value') : new static([]);
}

/**
* Retrieve a collection of cases sorted by value descending
*
* @return static
*/
public function sortDescByValue(): static
{
return $this->enumIsBacked ? $this->sortDescBy('value') : new static([]);
}
}
Loading

0 comments on commit 42a16a8

Please sign in to comment.