diff --git a/src/Trait/EnumTrait.php b/src/Trait/EnumTrait.php new file mode 100644 index 0000000..b9b3832 --- /dev/null +++ b/src/Trait/EnumTrait.php @@ -0,0 +1,126 @@ +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 + )); + } + } +}