Skip to content

Commit

Permalink
Fix some phpstan errors
Browse files Browse the repository at this point in the history
  • Loading branch information
xHeaven committed Dec 27, 2024
1 parent c77abe2 commit 16de68c
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 36 deletions.
8 changes: 3 additions & 5 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ parameters:
paths:
- src
- tests/FunctionTest.php
- tests/Enums
scanFiles:
- vendor/pestphp/pest/src/Functions.php
tmpDir: build/phpstan
reportUnmatchedIgnoredErrors: true
ignoreErrors:
- identifier: argument.templateType
- identifier: missingType.iterableValue
-
identifier: trait.unused
path: src/EnumConcern.php
count: 1
- identifier: missingType.generics
136 changes: 105 additions & 31 deletions src/EnumConcern.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ trait EnumConcern
*/
public static function isBackedEnum(): bool
{
// @phpstan-ignore function.alreadyNarrowedType, function.impossibleType
return is_subclass_of(static::class, BackedEnum::class);
}

Expand All @@ -26,7 +27,7 @@ public static function isBackedEnum(): bool
*/
public static function values(): Collection
{
if (static::isBackedEnum()) {
if (self::isBackedEnum()) {
return self::toCollection()->pluck('value');
}

Expand All @@ -45,10 +46,15 @@ public static function names(): Collection
/**
* Converts the enum cases into an associative array with names as keys and values as values.
* For pure enums, the values are the names.
*
* @return array<string, string|int>
*/
public static function toArray(): array
{
return self::toKeyValueCollection()->toArray();
/** @var array<string, string|int> $result */
$result = self::toKeyValueCollection()->toArray();

return $result;
}

/**
Expand All @@ -65,10 +71,14 @@ public static function toCollection(): Collection
*/
public static function toSelectCollection(): Collection
{
// @phpstan-ignore argument.type
return self::toCollection()->mapWithKeys(function (UnitEnum $case) {
$key = static::isBackedEnum() ? $case->value : $case->name;
if (self::isBackedEnum()) {
/** @var BackedEnum $case */
return [$case->value => self::getLabel($case)];
}

return [$key => self::getLabel($case)];
return [$case->name => self::getLabel($case)];
});
}

Expand All @@ -77,6 +87,7 @@ public static function toSelectCollection(): Collection
*/
public static function labels(): Collection
{
// @phpstan-ignore argument.type
return self::toCollection()->mapWithKeys(fn (UnitEnum $case) => [$case->name => self::getLabel($case)]);
}

Expand All @@ -94,16 +105,20 @@ public static function getLabel(UnitEnum $case): string
*/
public static function random(?int $count = null): Collection|static
{
return self::toCollection()->random($count);
/** @var Collection|static $result */
$result = self::toCollection()->random($count);

return $result;
}

/**
* Attempts to return the enum case for the given value; returns null if not found.
* For pure enums, uses the name instead.
*/
public static function tryFromValue(mixed $value): ?static
public static function tryFromValue(string|int $value): ?static
{
if (static::isBackedEnum()) {
if (self::isBackedEnum()) {
// @phpstan-ignore staticMethod.notFound
return static::tryFrom($value);
}

Expand All @@ -116,16 +131,19 @@ public static function tryFromValue(mixed $value): ?static
*/
public static function tryFromName(string $name): ?static
{
return self::toCollection()->firstWhere('name', $name);
/** @var ?static $result */
$result = self::toCollection()->firstWhere('name', $name);

return $result;
}

/**
* Checks if the enum contains the specified value; returns a boolean.
* For pure enums, checks the name.
*/
public static function hasValue(mixed $value): bool
public static function hasValue(string|int $value): bool
{
if (static::isBackedEnum()) {
if (self::isBackedEnum()) {
return self::values()->contains($value);
}

Expand Down Expand Up @@ -168,12 +186,20 @@ public function getDescription(): string

/**
* Returns attributes associated with the enum case.
*
* @return array<mixed>
*/
public function getAttributes(): array
{
$reflection = new ReflectionClass($this);
$caseName = $this->name;
$attrs = $reflection->getReflectionConstant($caseName)?->getAttributes() ?? [];
$reflectionConstant = $reflection->getReflectionConstant($caseName);

if ($reflectionConstant === false) {
return [];
}

$attrs = $reflectionConstant->getAttributes();

$attributes = [];
foreach ($attrs as $attr) {
Expand All @@ -189,9 +215,17 @@ public function getAttributes(): array
public function next(): ?static
{
$cases = self::toCollection();
/** @var int|false $index */
$index = $cases->search($this, strict: true);

return $cases->get($index + 1);
if ($index === false) {
return null;
}

/** @var ?static $result */
$result = $cases->get($index + 1);

return $result;
}

/**
Expand All @@ -200,9 +234,17 @@ public function next(): ?static
public function previous(): ?static
{
$cases = self::toCollection();
/** @var int|false $index */
$index = $cases->search($this, strict: true);

return $cases->get($index - 1);
if ($index === false) {
return null;
}

/** @var ?static $result */
$result = $cases->get($index - 1);

return $result;
}

/**
Expand Down Expand Up @@ -231,22 +273,26 @@ public static function toJson(): string
*/
public static function fromJson(string $json): Collection
{
/** @var list<string|int> $data */
$data = json_decode($json, true);

if (static::isBackedEnum()) {
return collect($data)->map(fn (mixed $value) => static::from($value));
if (self::isBackedEnum()) {
// @phpstan-ignore staticMethod.notFound
return collect($data)->map(fn (int|string $value) => static::from($value));
}

// For pure enums, keys are names
return collect($data)->keys()->map(fn (string $name) => self::tryFromName($name));
/** @var list<string> $data */
return collect($data)->map(fn (string $name) => self::tryFromName($name));
}

/**
* Provides validation rules for the enum, useful for Form Requests.
*
* @return array<string>
*/
public static function rules(): array
{
$values = static::isBackedEnum() ? self::values() : self::names();
$values = self::isBackedEnum() ? self::values() : self::names();

return ['in:' . $values->implode(',')];
}
Expand All @@ -256,10 +302,14 @@ public static function rules(): array
*/
public static function transLabels(): Collection
{
// @phpstan-ignore argument.type
return self::toCollection()->mapWithKeys(function (UnitEnum $case) {
$key = static::isBackedEnum() ? $case->value : $case->name;
if (self::isBackedEnum()) {
/** @var BackedEnum $case */
return [$case->value => __($case->name)];
}

return [$key => __($case->name)];
return [$case->name => __($case->name)];
});
}

Expand All @@ -275,9 +325,9 @@ public static function selectOptions(): Collection
* Retrieves the name/key associated with a given value.
* For pure enums, returns the name if it exists.
*/
public static function getKeyByValue(mixed $value): ?string
public static function getKeyByValue(string|int $value): ?string
{
if (static::isBackedEnum()) {
if (self::isBackedEnum()) {
return self::tryFromValue($value)?->name;
}

Expand All @@ -289,9 +339,10 @@ public static function getKeyByValue(mixed $value): ?string
* Retrieves the value associated with a given name/key.
* For pure enums, value is the name.
*/
public static function getValueByKey(string $key): mixed
public static function getValueByKey(string $key): string|int|null
{
if (static::isBackedEnum()) {
if (self::isBackedEnum()) {
// @phpstan-ignore property.notFound
return self::tryFromName($key)?->value;
}

Expand Down Expand Up @@ -345,7 +396,15 @@ public static function groupBy(string|callable $property): Collection
public static function sort(string $direction = 'asc'): Collection
{
$sorted = self::toCollection()->sortBy(
callback: fn (UnitEnum $case) => static::isBackedEnum() ? $case->value : $case->name,
// @phpstan-ignore argument.type
callback: function (UnitEnum $case) {
if (self::isBackedEnum()) {
/** @var BackedEnum $case */
return $case->value;
}

return $case->name;
},
options: SORT_REGULAR,
descending: ($direction === 'desc')
);
Expand All @@ -364,7 +423,7 @@ public static function slice(int $offset, ?int $length = null): Collection
/**
* Checks if a value or name exists within the enum cases.
*/
public static function contains(mixed $valueOrName): bool
public static function contains(string|int $valueOrName): bool
{
return self::hasValue($valueOrName) || self::hasName((string)$valueOrName);
}
Expand All @@ -375,35 +434,50 @@ public static function contains(mixed $valueOrName): bool
*/
public static function toKeyValueCollection(): Collection
{
// @phpstan-ignore argument.type
return self::toCollection()->mapWithKeys(function (UnitEnum $case) {
$value = static::isBackedEnum() ? $case->value : $case->name;
if (self::isBackedEnum()) {
/** @var BackedEnum $case */
return [$case->name => $case->value];
}

return [$case->name => $value];
return [$case->name => $case->name];
});
}

/**
* Lists all constants defined in the enum class.
*
* @return array<string, static>
*/
public static function listConstants(): array
{
return (new ReflectionClass(static::class))->getConstants();
/** @var array<string, static> $result */
$result = (new ReflectionClass(static::class))->getConstants();

return $result;
}

/**
* Return the first case (or null if empty).
*/
public static function first(): ?static
{
return self::toCollection()->first();
/** @var ?static $result */
$result = self::toCollection()->first();

return $result;
}

/**
* Return the last case (or null if empty).
*/
public static function last(): ?static
{
return self::toCollection()->last();
/** @var ?static $result */
$result = self::toCollection()->last();

return $result;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions tests/FunctionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
* Helper function to test methods across different enums.
*
* @param class-string $enumClass
* @param array<string|int> $expectedValues
* @param array<string> $expectedNames
* @param array<string, string|int> $expectedArray
*/
function testEnumMethods(string $enumClass, array $expectedValues, array $expectedNames, array $expectedArray): void
{
Expand Down

0 comments on commit 16de68c

Please sign in to comment.