mirror of
https://github.com/archtechx/enums.git
synced 2025-12-12 06:44:04 +00:00
initial
This commit is contained in:
parent
f9fe9e5cab
commit
41b423da38
11 changed files with 146 additions and 91 deletions
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
|
|
@ -3,7 +3,6 @@ name: CI
|
||||||
env:
|
env:
|
||||||
COMPOSE_INTERACTIVE_NO_CLI: 1
|
COMPOSE_INTERACTIVE_NO_CLI: 1
|
||||||
PHP_CS_FIXER_IGNORE_ENV: 1
|
PHP_CS_FIXER_IGNORE_ENV: 1
|
||||||
MYSQL_PORT: 3307
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
@ -21,8 +20,6 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Start docker containers
|
|
||||||
run: docker-compose up -d
|
|
||||||
- name: Install composer dependencies
|
- name: Install composer dependencies
|
||||||
run: composer require "illuminate/support:^${{ matrix.laravel }}.0"
|
run: composer require "illuminate/support:^${{ matrix.laravel }}.0"
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
|
|
||||||
72
README.md
72
README.md
|
|
@ -1,27 +1,75 @@
|
||||||
# REPLACE
|
# Enums
|
||||||
|
|
||||||
Simple and flexible package template. Supports Laravel 8 and 9.
|
A collection\* of enum helpers for PHP.
|
||||||
|
|
||||||
# Usage
|
\* Currently there's only one helper — [`InvokableCases`](#invokablecases) — but the goal of the package is to provide general purpose enum helpers.
|
||||||
|
|
||||||
- Replace all occurances of `REPLACE` (case sensitive) with the name of the package namespace. E.g. the `Foo` in `ArchTech\Foo`.
|
You can read more about the idea on [Twitter](https://twitter.com/archtechx/status/1495158228757270528). I originally wanted to include that helper in [`archtechx/helpers`](https://github.com/archtechx/helpers), but it makes more sense to make this a separate dependency and use it *inside* the other package.
|
||||||
- Also do this for file names, e.g. `REPLACEServiceProvider.php`.
|
|
||||||
- Replace all occurances of `replace` with the name of the package on composer, e.g. the `bar` in `archtechx/bar`.
|
|
||||||
- If MySQL is not needed, remove `docker-compose.yml`, remove the line that runs docker from `./check`, and remove it from the `.github/ci.yml` file.
|
|
||||||
- If SQLite is wanted, change `DB_CONNECTION` in `phpunit.xml` to `sqlite`, and `DB_DATABASE` to `:memory:`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
Laravel 8 or 9 are required. PHP 8.1+ is required.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
composer require archtechx/replace
|
composer require archtechx/enums
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### InvokableCases
|
||||||
|
|
||||||
|
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()`).
|
||||||
|
|
||||||
|
That way, you can use enums as array keys:
|
||||||
```php
|
```php
|
||||||
// ...
|
'statuses' => [
|
||||||
|
TaskStatus::INCOMPLETE() => ['some configuration'],
|
||||||
|
TaskStatus::COMPLETED() => ['some configuration'],
|
||||||
|
],
|
||||||
|
```
|
||||||
|
|
||||||
|
Or just the underlying primitives for any other use cases:
|
||||||
|
```php
|
||||||
|
public function updateStatus(int $status): void;
|
||||||
|
|
||||||
|
$task->updateStatus(TaskStatus::COMPLETED());
|
||||||
|
```
|
||||||
|
|
||||||
|
Without [having to append](https://twitter.com/archtechx/status/1495158237137494019) `->value` to everything.
|
||||||
|
|
||||||
|
This approach also has *decent* IDE support. You get autosuggestions while typing, and then you just append `()`:
|
||||||
|
```php
|
||||||
|
MyEnum::FOO; // => MyEnum instance
|
||||||
|
MyEnum::FOO(); // => 1
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Apply the trait on your enum
|
||||||
|
```php
|
||||||
|
use ArchTech\Enums\InvokableCases;
|
||||||
|
|
||||||
|
enum TaskStatus: int
|
||||||
|
{
|
||||||
|
use InvokableCases;
|
||||||
|
|
||||||
|
case INCOMPLETE = 0;
|
||||||
|
case COMPLETED = 1;
|
||||||
|
case CANCELED = 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Use static calls to get the primitive value
|
||||||
|
```php
|
||||||
|
TaskStatus::INCOMPLETE(); // 0
|
||||||
|
TaskStatus::COMPLETED(); // 1
|
||||||
|
TaskStatus::CANCELED(); // 2
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Invoke instances to get the primitive value
|
||||||
|
```php
|
||||||
|
public function updateStatus(TaskStatus $status)
|
||||||
|
{
|
||||||
|
$this->record->setStatus($status());
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "archtechx/replace",
|
"name": "archtechx/enums",
|
||||||
"description": "",
|
"description": "Helpers that make PHP enums more lovable",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"authors": [
|
"authors": [
|
||||||
|
|
@ -11,17 +11,16 @@
|
||||||
],
|
],
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"ArchTech\\REPLACE\\": "src/"
|
"ArchTech\\Enums\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"ArchTech\\REPLACE\\Tests\\": "tests/"
|
"ArchTech\\Enums\\Tests\\": "tests/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.0",
|
"php": "^8.1"
|
||||||
"illuminate/support": "^8.24|^9.0"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"orchestra/testbench": "^6.9|^7.0",
|
"orchestra/testbench": "^6.9|^7.0",
|
||||||
|
|
@ -29,13 +28,11 @@
|
||||||
"pestphp/pest": "^1.2",
|
"pestphp/pest": "^1.2",
|
||||||
"pestphp/pest-plugin-laravel": "^1.0"
|
"pestphp/pest-plugin-laravel": "^1.0"
|
||||||
},
|
},
|
||||||
"extra": {
|
|
||||||
"laravel": {
|
|
||||||
"providers": [
|
|
||||||
"ArchTech\\REPLACE\\PackageServiceProvider"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"prefer-stable": true
|
"prefer-stable": true,
|
||||||
|
"config": {
|
||||||
|
"allow-plugins": {
|
||||||
|
"pestphp/pest-plugin": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
version: '3'
|
|
||||||
services:
|
|
||||||
mysql:
|
|
||||||
image: mysql:5.7
|
|
||||||
environment:
|
|
||||||
MYSQL_ROOT_PASSWORD: password
|
|
||||||
MYSQL_DATABASE: main
|
|
||||||
MYSQL_USER: user
|
|
||||||
MYSQL_PASSWORD: password
|
|
||||||
MYSQL_TCP_PORT: ${MYSQL_PORT}
|
|
||||||
ports:
|
|
||||||
- "${MYSQL_PORT}:${MYSQL_PORT}"
|
|
||||||
16
src/Exceptions/UndefinedCaseError.php
Normal file
16
src/Exceptions/UndefinedCaseError.php
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace ArchTech\Enums\Exceptions;
|
||||||
|
|
||||||
|
use Error;
|
||||||
|
|
||||||
|
class UndefinedCaseError extends Error
|
||||||
|
{
|
||||||
|
public function __construct(string $enum, string $case)
|
||||||
|
{
|
||||||
|
// Matches the error message of invalid Foo::BAR access
|
||||||
|
parent::__construct("Undefined constant $enum::$case");
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/InvokableCases.php
Normal file
28
src/InvokableCases.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace ArchTech\Enums;
|
||||||
|
|
||||||
|
trait InvokableCases
|
||||||
|
{
|
||||||
|
/** Return the enum's value when it's $invoked(). */
|
||||||
|
public function __invoke()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the enum's value when it's called ::STATICALLY(). */
|
||||||
|
public static function __callStatic($name, $args)
|
||||||
|
{
|
||||||
|
$cases = static::cases();
|
||||||
|
|
||||||
|
foreach ($cases as $case) {
|
||||||
|
if ($case->name === $name) {
|
||||||
|
return $case->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exceptions\UndefinedCaseError(static::class, $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace ArchTech\REPLACE;
|
|
||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
|
||||||
|
|
||||||
class REPLACEServiceProvider extends ServiceProvider
|
|
||||||
{
|
|
||||||
public function register(): void
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function boot(): void
|
|
||||||
{
|
|
||||||
// $this->loadViewsFrom(__DIR__ . '/../assets/views', 'replace');
|
|
||||||
|
|
||||||
// $this->publishes([
|
|
||||||
// __DIR__ . '/../assets/views' => resource_path('views/vendor/replace'),
|
|
||||||
// ], 'replace-views');
|
|
||||||
|
|
||||||
// $this->mergeConfigFrom(
|
|
||||||
// __DIR__ . '/../assets/replace.php',
|
|
||||||
// 'replace'
|
|
||||||
// );
|
|
||||||
|
|
||||||
// $this->publishes([
|
|
||||||
// __DIR__ . '/../assets/replace.php' => config_path('replace.php'),
|
|
||||||
// ], 'replace-config');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uses(ArchTech\REPLACE\Tests\TestCase::class)->in('Pest');
|
uses(ArchTech\Enums\Tests\TestCase::class)->in('Pest');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
28
tests/Pest/EnumTest.php
Normal file
28
tests/Pest/EnumTest.php
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use ArchTech\Enums\Exceptions\UndefinedCaseError;
|
||||||
|
use ArchTech\Enums\InvokableCases;
|
||||||
|
|
||||||
|
it('can be used as a static method', function () {
|
||||||
|
expect(Status::PENDING())->toBe(0);
|
||||||
|
expect(Status::DONE())->toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can be invoked as an instance', function () {
|
||||||
|
$status = Status::PENDING;
|
||||||
|
|
||||||
|
expect($status())->toBe(0);
|
||||||
|
expect($status())->toBe($status->value);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws an error when a nonexistent case is being used', function () {
|
||||||
|
Status::INVALID();
|
||||||
|
})->expectException(UndefinedCaseError::class);
|
||||||
|
|
||||||
|
enum Status: int
|
||||||
|
{
|
||||||
|
use InvokableCases;
|
||||||
|
|
||||||
|
case PENDING = 0;
|
||||||
|
case DONE = 1;
|
||||||
|
}
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
it('succeeds', function () {
|
|
||||||
expect(true)->toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('fails', function () {
|
|
||||||
expect(false)->toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
@ -1,16 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace ArchTech\REPLACE\Tests;
|
namespace ArchTech\Enums\Tests;
|
||||||
|
|
||||||
use Orchestra\Testbench\TestCase as TestbenchTestCase;
|
use Orchestra\Testbench\TestCase as TestbenchTestCase;
|
||||||
use ArchTech\REPLACE\REPLACEServiceProvider;
|
|
||||||
|
|
||||||
class TestCase extends TestbenchTestCase
|
class TestCase extends TestbenchTestCase
|
||||||
{
|
{
|
||||||
protected function getPackageProviders($app)
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
REPLACEServiceProvider::class,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue