Skip to content

Commit

Permalink
added Extractor
Browse files Browse the repository at this point in the history
  • Loading branch information
henzeb committed May 31, 2022
1 parent 24a2ecc commit d74f3ee
Show file tree
Hide file tree
Showing 16 changed files with 347 additions and 60 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to `Enumhancer` will be documented in this file

## 1.5.0 - 2022-05-31
- added `Extractor` to extract enums from a string mentioned by value
- some documentation repairs

## 1.4.1 - 2022-03-04

- added `cases` method to `Subset`
Expand All @@ -15,7 +19,7 @@ All notable changes to `Enumhancer` will be documented in this file

## 1.3.0 - 2022-02-28

- added Multi. Currently allows you to compare against a subset of your enum.
- added Multi. Currently allows you to compare against a subset of your enum

## 1.2.0 - 2022-02-26

Expand Down
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@
[![Latest Version on Packagist](https://img.shields.io/packagist/v/henzeb/enumhancer.svg?style=flat-square)](https://packagist.org/packages/henzeb/enumhancer)
[![Total Downloads](https://img.shields.io/packagist/dt/henzeb/enumhancer.svg?style=flat-square)](https://packagist.org/packages/henzeb/enumhancer)

In this library you'll find some of the most common use-cases for enums.
If you find yourself recreating functionalities, maybe this package is
something for you.
This package is your Swiss Army knife when it comes to PHP 8.1's enums.
In this package you will find a lot of tools for the most common use cases
and more will be added in the future.

If you have an idea or you miss something that needs to be added,
just let me know.

This package currently supports the following:

- Constructor (in case you're migrating from
[Spatie's PHP Enum](https://github.com/spatie/enum))
- Comparison
- Extractor
- From (for unit enums)
- Make (Ability to make from enum-name)
- Labels
- Make (Ability to make from enum-name)
- Mappers
- Multi
- Properties
- Reporting (Logging)
- Value

- Subset
- Value (for unit enums)

## Installation

Expand Down Expand Up @@ -48,18 +51,19 @@ You can also just use one of the functionalities by using the specific trait
for that functionality.

Note: all traits can be used next to each other, except for `Mappers`, which has
implemented his own version of `Makers` and `Reporters`.
implemented the methods of `Makers`, `Extractor` and `Reporters`.

### Functionality
- [Constructor](docs/constructor.md)
- [Comparison](docs/comparison.md)
- [Extractor](docs/extractor.md)
- [From](docs/from.md)
- [Labels](docs/labels.md)
- [Makers](docs/makers.md)
- [Mappers](docs/mappers.md)
- [Subset](docs/subset.md)
- [Properties](docs/properties.md)
- [Reporters](docs/reporters.md)
- [Subset](docs/subset.md)
- [Value](docs/value.md)

### Laravel
Expand Down
8 changes: 7 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
"description": "Enrich your enums with common functionality",
"keywords": [
"henzeb",
"enumhancer"
"enumhancer",
"enums",
"enum",
"enumerators",
"enumerator",
"mappers",
"comparison"
],
"homepage": "https://github.com/henzeb/enumhancer",
"license": "AGPL-3.0-only",
Expand Down
26 changes: 26 additions & 0 deletions docs/extractor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Extractor
Sometimes you have a piece of text that contains an enum value that you
want to use. With this you can simply pass a multiline string and extract all
enums that are mentioned by value.

Note: This also works with `Mappers`.

## Usage
```php
use Henzeb\Enumhancer\Concerns\Extractor;

enum YourEnum: string {
use Extractor;

case ENUM = 'enum';
case ENUM2 = 'another enum';
}
```

### Examples
```php
YourEnum::extract('you can find another enum here'); // returns [YourEnum::ENUM2]
YourEnum::extract('A lot of text with (enum)'); // returns [YourEnum::ENUM]
YourEnum::extract('another enum (enum)'); // returns [YourEnum::ENUM2, YourEnum::ENUM]
YourEnum::extract('extact case sensitive another ENUM') // returns [YourEnum::ENUM2];
```
8 changes: 4 additions & 4 deletions docs/from.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# From

The methods `from` and `tryFrom` do not exist on non-backed enums. When you have
a non-backed enum where the string value is exactly the same as it's key, but
you need `from` or `tryFrom` because of some library (like Laravel's validation),
this might be useful.
The methods `from` and `tryFrom` do not exist on non-backed enums. When you
have a non-backed enum where the string value is exactly the same as it's key,
but you need `from` or `tryFrom` because of some library (like Laravel's
validation), this might be useful.

## Usage

Expand Down
12 changes: 9 additions & 3 deletions docs/mappers.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ for example are building against multiple third party API's and you
need to translate the enums between one and other.

Note: `Mappers` is the only one that you cannot use together with
`Makers` and `Reporters`. This is simply due to the fact that it is
`Makers`, `Extractor` and `Reporters`. This is simply due to the fact that it is
implementing the methods for those by itself. Under the hood it's using
their functionality, so the methods will work just the same.

Expand Down Expand Up @@ -62,11 +62,16 @@ YourEnum::makeArray(['unknown', 'NOT_MAPPED'], new YourMapper()); // will throw
YourEnum::tryMakeArray(['Mapped', 'NOT_MAPPED'], YourMapper::class); // will return [YourEnum::ENUM, YourEnum::NOT_MAPPED]
YourEnum::tryMakeArray(['unknown', 'NOT_MAPPED'], new YourMapper()); // will return [YourEnum::NOT_MAPPED]

/** tryMakeArray */
/** makeOrReport */
YourEnum::makeOrReport(['Mapped', 'NOT_MAPPED'], YourMapper::class); // will return [YourEnum::ENUM, YourEnum::NOT_MAPPED]
YourEnum::makeOrReport(['unknown', 'NOT_MAPPED'], new YourMapper()); // will return [YourEnum::NOT_MAPPED]

/** extract */
YourEnum::extract('a sentence with Mapped in it', YourMapper::class); // will return [YourEnum::ENUM]
YourEnum::extract('a sentence with Mapped in it', new YourMapper()); // will return [YourEnum::ENUM]
```
Note: See for the `makeOrReport` method: [Reporters](reporters.md)
Note: See for the `extract` method: [Extractor](extractor.md)

### Shared Mapper

Expand All @@ -93,7 +98,8 @@ And then use the commands as shown in the `example` section.

## The mapper method

In case you don't want to add the mapper all the time, you can also specify a `mapper` method that returns your mapper.
In case you don't want to add the mapper all the time, you can also specify
a `mapper` method that returns your mapper.

```php
use Henzeb\Enumhancer\Concerns\Mappers;
Expand Down
13 changes: 13 additions & 0 deletions src/Concerns/Extractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Henzeb\Enumhancer\Concerns;

use Henzeb\Enumhancer\Helpers\EnumExtractor;

trait Extractor
{
public static function extract(string $text): array
{
return EnumExtractor::extract(self::class, $text);
}
}
70 changes: 33 additions & 37 deletions src/Concerns/Mappers.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
use Henzeb\Enumhancer\Contracts\Mapper;
use Henzeb\Enumhancer\Contracts\Reporter;
use Henzeb\Enumhancer\Helpers\EnumMakers;
use Henzeb\Enumhancer\Helpers\EnumMapper;
use Henzeb\Enumhancer\Helpers\EnumReporter;
use Henzeb\Enumhancer\Helpers\EnumExtractor;

trait Mappers
{
protected static function reporter():?Reporter
protected static function reporter(): ?Reporter
{
return EnumReporter::get();
}
Expand All @@ -20,62 +22,56 @@ protected static function mapper(): ?Mapper
return null;
}

private static function map(string|int|null $value, Mapper|string $mapper = null): ?string
{
if(null === $value) {
return null;
}

$value = ($mapper) ?
$mapper->map($value, static::class) ?? $value
: $value;

return ($mapper = self::mapper()) ?
$mapper->map($value, static::class) ?? $value
: $value;
}

final public static function make(string|int|null $value, Mapper|string $mapper = null): self
{
return EnumMakers::make(self::class, self::map($value, $mapper));
return EnumMakers::make(self::class, EnumMapper::map($value, $mapper, self::mapper()));
}

final public static function tryMake(string|int|null $value, Mapper|string $mapper = null): ?self
{
return EnumMakers::tryMake(self::class, self::map($value, $mapper));
return EnumMakers::tryMake(self::class, EnumMapper::map($value, $mapper, self::mapper()));
}

final public static function makeArray(iterable $values, Mapper|string $mapper = null): array
{
$mapped = [];
foreach($values as $value) {
$mapped[] = self::map($value, $mapper);
}
return EnumMakers::makeArray(self::class, $mapped);

return EnumMakers::makeArray(
self::class,
EnumMapper::mapArray($values, $mapper, self::mapper())
);
}

final public static function tryMakeArray(iterable $values, Mapper|string $mapper = null): array
{
$mapped = [];
foreach($values as $value) {
$mapped[] = self::map($value, $mapper);
}
return EnumMakers::tryMakeArray(self::class, $mapped);
return EnumMakers::tryMakeArray(
self::class,
EnumMapper::mapArray($values, $mapper, self::mapper())
);
}

final public static function makeOrReport(int|string|null $values, BackedEnum $context = null, Mapper $mapper = null): ?self
final public static function makeOrReport(int|string|null $value, BackedEnum $context = null, Mapper|string $mapper = null): ?self
{
return EnumReporter::makeOrReport(self::class, self::map($values, $mapper), $context, self::reporter());
return EnumReporter::makeOrReport(self::class, EnumMapper::map($value, $mapper, self::mapper()), $context, self::reporter());
}

public static function makeOrReportArray(iterable $values, BackedEnum $context = null, Mapper $mapper = null): array
public static function makeOrReportArray(iterable $values, BackedEnum $context = null, Mapper|string $mapper = null): array
{
$mapped = [];
foreach($values as $value) {
$mapped[] = self::map($value, $mapper);
}

return EnumReporter::makeOrReportArray(self::class, $mapped, $context, self::reporter());
return EnumReporter::makeOrReportArray(
self::class,
EnumMapper::mapArray($values, $mapper, self::mapper()),
$context,
self::reporter()
);
}

public static function extract(string $text, Mapper|string $mapper = null): array
{
$mappers = array_filter(
[
is_string($mapper) ? new $mapper() : $mapper, self::mapper()
]
);

return EnumExtractor::extract(self::class, $text, ...$mappers);
}
}
20 changes: 19 additions & 1 deletion src/Contracts/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ private function parse(mixed $value): ?string
return null;
}

if(empty($value)) {
if (empty($value)) {
return null;
}

Expand All @@ -40,4 +40,22 @@ public function defined(string $key, string $prefix = null): bool
{
return (bool)$this->map($key, $prefix);
}

public function keys(string $prefix = null): array
{
$mappable = $this->mappable();

return array_merge(
array_keys(

array_filter(
$mappable,
function ($value) {
return !is_array($value);
}
),
),
is_array($mappable[$prefix] ?? null) ? $mappable[$prefix] : []
);
}
}
45 changes: 45 additions & 0 deletions src/Helpers/EnumExtractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Henzeb\Enumhancer\Helpers;

use UnitEnum;
use Henzeb\Enumhancer\Contracts\Mapper;
use Henzeb\Enumhancer\Concerns\Mappers;

class EnumExtractor
{
use Mappers;

public static function extract(string $class, string $text, Mapper ...$mappers): array
{
EnumCheck::check($class);

/**
* @var $class UnitEnum|string
*/

$match = array_map(
function ($enum) {

if (property_exists($enum, 'value')) {
return $enum->value;
}

return $enum->name;
}, $class::cases()
);

$match = implode(
'|',
array_merge(
$match,
...array_map(fn(Mapper $map) => $map->keys($class), $mappers)
));

preg_match_all(sprintf('/%s/i', $match), $text, $matches);

$matches = array_map(fn($value) => EnumMapper::map($value, ...$mappers), $matches[0] ?? []);

return EnumMakers::makeArray($class, $matches);
}
}
Loading

0 comments on commit d74f3ee

Please sign in to comment.