核心库新增EnumTrait
This commit is contained in:
126
src/Trait/EnumTrait.php
Normal file
126
src/Trait/EnumTrait.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dhd\Micro\Core\Trait;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* PHP 原生枚举辅助方法(values/descriptions/valueMap/fromValue 等).
|
||||
*/
|
||||
trait EnumTrait
|
||||
{
|
||||
public static function values(): array
|
||||
{
|
||||
self::validateEnumStructure();
|
||||
|
||||
$values = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$values[] = $case->value;
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
public static function descriptions(): array
|
||||
{
|
||||
self::validateEnumStructure();
|
||||
|
||||
$descriptions = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$descriptions[] = $case->description();
|
||||
}
|
||||
return $descriptions;
|
||||
}
|
||||
|
||||
public static function valueMap(): array
|
||||
{
|
||||
self::validateEnumStructure();
|
||||
|
||||
$map = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$map[$case->value] = $case->description();
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
public static function fromValue(int|string $value): self
|
||||
{
|
||||
self::validateEnumStructure();
|
||||
|
||||
$firstCase = self::cases()[0] ?? null;
|
||||
if ($firstCase) {
|
||||
$expectedType = gettype($firstCase->value);
|
||||
$actualType = gettype($value);
|
||||
if ($expectedType !== $actualType) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'枚举值类型不匹配,%s期望%s类型,实际为%s',
|
||||
self::class,
|
||||
$expectedType,
|
||||
$actualType
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$enum = self::tryFrom($value);
|
||||
if (! $enum) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'无效的%s值: %s,允许值: %s',
|
||||
self::class,
|
||||
$value,
|
||||
implode(', ', self::values())
|
||||
));
|
||||
}
|
||||
return $enum;
|
||||
}
|
||||
|
||||
public static function fromDescription(string $description): ?self
|
||||
{
|
||||
self::validateEnumStructure();
|
||||
|
||||
foreach (self::cases() as $case) {
|
||||
if ($case->description() === $description) {
|
||||
return $case;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function isValidValue(int|string $value): bool
|
||||
{
|
||||
self::validateEnumStructure();
|
||||
|
||||
foreach (self::cases() as $case) {
|
||||
if ($case->value === $value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function validateEnumStructure(): void
|
||||
{
|
||||
if (! (new ReflectionClass(self::class))->isEnum()) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'EnumTrait仅允许枚举类使用,%s不是枚举',
|
||||
self::class
|
||||
));
|
||||
}
|
||||
|
||||
if (! method_exists(self::class, 'description')) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'枚举类%s必须实现description()方法(返回字符串描述)',
|
||||
self::class
|
||||
));
|
||||
}
|
||||
|
||||
$sampleCase = self::cases()[0] ?? null;
|
||||
if ($sampleCase && ! is_string($sampleCase->description())) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'枚举类%s的description()方法必须返回字符串',
|
||||
self::class
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user